aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJody McIntyre <scjody@modernduck.com>2006-01-05 22:22:50 -0500
committerJody McIntyre <scjody@modernduck.com>2006-01-05 22:22:50 -0500
commit52cab57873c25d3c8324ee3e4d463db6e8e73fd7 (patch)
tree826cb36827afa363944e6478d19512e669446c64
parent0a75c23a009ff65f651532cecc16675d05f4de37 (diff)
parent46f25dffbaba48c571d75f5f574f31978287b8d2 (diff)
Merge with http://kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
-rw-r--r--Documentation/pcmcia/driver-changes.txt11
-rw-r--r--arch/ia64/kernel/setup.c2
-rw-r--r--arch/ia64/pci/pci.c2
-rw-r--r--drivers/base/power/runtime.c1
-rw-r--r--drivers/bluetooth/bluecard_cs.c109
-rw-r--r--drivers/bluetooth/bt3c_cs.c110
-rw-r--r--drivers/bluetooth/btuart_cs.c110
-rw-r--r--drivers/bluetooth/dtl1_cs.c111
-rw-r--r--drivers/char/pcmcia/cm4000_cs.c162
-rw-r--r--drivers/char/pcmcia/cm4040_cs.c151
-rw-r--r--drivers/char/pcmcia/synclink_cs.c132
-rw-r--r--drivers/ide/legacy/ide-cs.c132
-rw-r--r--drivers/isdn/hardware/avm/avm_cs.c145
-rw-r--r--drivers/isdn/hisax/avma1_cs.c150
-rw-r--r--drivers/isdn/hisax/elsa_cs.c158
-rw-r--r--drivers/isdn/hisax/sedlbauer_cs.c169
-rw-r--r--drivers/isdn/hisax/teles_cs.c149
-rw-r--r--drivers/mtd/maps/pcmciamtd.c121
-rw-r--r--drivers/net/pcmcia/3c574_cs.c124
-rw-r--r--drivers/net/pcmcia/3c589_cs.c136
-rw-r--r--drivers/net/pcmcia/axnet_cs.c128
-rw-r--r--drivers/net/pcmcia/com20020_cs.c142
-rw-r--r--drivers/net/pcmcia/fmvj18x_cs.c128
-rw-r--r--drivers/net/pcmcia/ibmtr_cs.c152
-rw-r--r--drivers/net/pcmcia/nmclan_cs.c134
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c129
-rw-r--r--drivers/net/pcmcia/smc91c92_cs.c195
-rw-r--r--drivers/net/pcmcia/xirc2ps_cs.c158
-rw-r--r--drivers/net/wireless/airo_cs.c161
-rw-r--r--drivers/net/wireless/atmel_cs.c156
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c156
-rw-r--r--drivers/net/wireless/netwave_cs.c184
-rw-r--r--drivers/net/wireless/orinoco_cs.c208
-rw-r--r--drivers/net/wireless/ray_cs.c154
-rw-r--r--drivers/net/wireless/spectrum_cs.c175
-rw-r--r--drivers/net/wireless/wavelan_cs.c183
-rw-r--r--drivers/net/wireless/wavelan_cs.p.h11
-rw-r--r--drivers/net/wireless/wl3501_cs.c133
-rw-r--r--drivers/parport/parport_cs.c120
-rw-r--r--drivers/pcmcia/Kconfig32
-rw-r--r--drivers/pcmcia/au1000_generic.c21
-rw-r--r--drivers/pcmcia/cistpl.c36
-rw-r--r--drivers/pcmcia/cs.c102
-rw-r--r--drivers/pcmcia/cs_internal.h4
-rw-r--r--drivers/pcmcia/ds.c351
-rw-r--r--drivers/pcmcia/hd64465_ss.c13
-rw-r--r--drivers/pcmcia/i82092.c73
-rw-r--r--drivers/pcmcia/i82092aa.h1
-rw-r--r--drivers/pcmcia/i82365.c83
-rw-r--r--drivers/pcmcia/m32r_cfc.c32
-rw-r--r--drivers/pcmcia/m32r_pcc.c20
-rw-r--r--drivers/pcmcia/m8xx_pcmcia.c114
-rw-r--r--drivers/pcmcia/pd6729.c74
-rw-r--r--drivers/pcmcia/pxa2xx_mainstone.c3
-rw-r--r--drivers/pcmcia/pxa2xx_sharpsl.c3
-rw-r--r--drivers/pcmcia/rsrc_mgr.c108
-rw-r--r--drivers/pcmcia/rsrc_nonstatic.c140
-rw-r--r--drivers/pcmcia/soc_common.c23
-rw-r--r--drivers/pcmcia/socket_sysfs.c30
-rw-r--r--drivers/pcmcia/tcic.c61
-rw-r--r--drivers/pcmcia/ti113x.h4
-rw-r--r--drivers/pcmcia/vrc4171_card.c70
-rw-r--r--drivers/pcmcia/vrc4173_cardu.c43
-rw-r--r--drivers/pcmcia/yenta_socket.c140
-rw-r--r--drivers/scsi/pcmcia/aha152x_stub.c99
-rw-r--r--drivers/scsi/pcmcia/fdomain_stub.c117
-rw-r--r--drivers/scsi/pcmcia/nsp_cs.c167
-rw-r--r--drivers/scsi/pcmcia/nsp_cs.h4
-rw-r--r--drivers/scsi/pcmcia/qlogic_stub.c127
-rw-r--r--drivers/scsi/pcmcia/sym53c500_cs.c133
-rw-r--r--drivers/serial/serial_cs.c119
-rw-r--r--drivers/telephony/ixj_pcmcia.c112
-rw-r--r--drivers/usb/host/sl811_cs.c110
-rw-r--r--drivers/video/aty/atyfb_base.c2
-rw-r--r--include/linux/netfilter/nfnetlink_conntrack.h5
-rw-r--r--include/linux/netfilter_ipv6/ip6_tables.h6
-rw-r--r--include/net/ip.h1
-rw-r--r--include/net/netfilter/nf_conntrack.h31
-rw-r--r--include/net/netfilter/nf_conntrack_helper.h2
-rw-r--r--include/net/netfilter/nf_conntrack_l3proto.h15
-rw-r--r--include/net/netfilter/nf_conntrack_protocol.h26
-rw-r--r--include/pcmcia/cs.h2
-rw-r--r--include/pcmcia/ds.h13
-rw-r--r--include/pcmcia/ss.h4
-rw-r--r--net/bridge/br_if.c5
-rw-r--r--net/ethernet/eth.c5
-rw-r--r--net/ipv4/ip_gre.c5
-rw-r--r--net/ipv4/ip_output.c30
-rw-r--r--net/ipv4/ipip.c3
-rw-r--r--net/ipv4/ipmr.c3
-rw-r--r--net/ipv4/ipvs/ip_vs_conn.c1
-rw-r--r--net/ipv4/ipvs/ip_vs_core.c5
-rw-r--r--net/ipv4/ipvs/ip_vs_est.c1
-rw-r--r--net/ipv4/ipvs/ip_vs_sched.c1
-rw-r--r--net/ipv4/netfilter/ip_conntrack_amanda.c2
-rw-r--r--net/ipv4/netfilter/ip_conntrack_ftp.c2
-rw-r--r--net/ipv4/netfilter/ip_conntrack_irc.c10
-rw-r--r--net/ipv4/netfilter/ip_conntrack_netbios_ns.c2
-rw-r--r--net/ipv4/netfilter/ip_conntrack_netlink.c36
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_icmp.c47
-rw-r--r--net/ipv4/netfilter/ip_conntrack_standalone.c26
-rw-r--r--net/ipv4/netfilter/ip_nat_standalone.c17
-rw-r--r--net/ipv4/netfilter/ipt_REJECT.c2
-rw-r--r--net/ipv4/netfilter/ipt_ULOG.c10
-rw-r--r--net/ipv4/netfilter/ipt_recent.c20
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c74
-rw-r--r--net/ipv4/netfilter/nf_conntrack_proto_icmp.c97
-rw-r--r--net/ipv6/netfilter/ip6_tables.c124
-rw-r--r--net/ipv6/netfilter/ip6t_ah.c2
-rw-r--r--net/ipv6/netfilter/ip6t_dst.c4
-rw-r--r--net/ipv6/netfilter/ip6t_esp.c2
-rw-r--r--net/ipv6/netfilter/ip6t_frag.c2
-rw-r--r--net/ipv6/netfilter/ip6t_hbh.c4
-rw-r--r--net/ipv6/netfilter/ip6t_rt.c2
-rw-r--r--net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c47
-rw-r--r--net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c77
-rw-r--r--net/ipv6/sit.c3
-rw-r--r--net/netfilter/Kconfig7
-rw-r--r--net/netfilter/Makefile3
-rw-r--r--net/netfilter/nf_conntrack_core.c239
-rw-r--r--net/netfilter/nf_conntrack_ftp.c2
-rw-r--r--net/netfilter/nf_conntrack_netlink.c1653
-rw-r--r--net/netfilter/nf_conntrack_proto_tcp.c71
-rw-r--r--net/netfilter/nf_conntrack_proto_udp.c10
-rw-r--r--net/netfilter/nf_conntrack_standalone.c42
-rw-r--r--net/netfilter/nfnetlink_queue.c79
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf.c154
-rw-r--r--sound/pcmcia/vx/vxpocket.c155
128 files changed, 5045 insertions, 5709 deletions
diff --git a/Documentation/pcmcia/driver-changes.txt b/Documentation/pcmcia/driver-changes.txt
index 403e7b4dcdd4..97420f08c786 100644
--- a/Documentation/pcmcia/driver-changes.txt
+++ b/Documentation/pcmcia/driver-changes.txt
@@ -1,5 +1,16 @@
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 well as attach and INSERTION
4 code (as of 2.6.16)
5 void (*remove) (struct pcmcia_device *dev);
6 int (*probe) (struct pcmcia_device *dev);
7
8* Move suspend, resume and reset out of event handler (as of 2.6.16)
9 int (*suspend) (struct pcmcia_device *dev);
10 int (*resume) (struct pcmcia_device *dev);
11 should be initialized in struct pcmcia_driver, and handle
12 (SUSPEND == RESET_PHYSICAL) and (RESUME == CARD_RESET) events
13
3* event handler initialization in struct pcmcia_driver (as of 2.6.13) 14* event handler initialization in struct pcmcia_driver (as of 2.6.13)
4 The event handler is notified of all events, and must be initialized 15 The event handler is notified of all events, and must be initialized
5 as the event() callback in the driver's struct pcmcia_driver. 16 as the event() callback in the driver's struct pcmcia_driver.
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index 088e5dded8dc..c33305d8e5eb 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -518,7 +518,7 @@ show_cpuinfo (struct seq_file *m, void *v)
518 char family[32], features[128], *cp, sep; 518 char family[32], features[128], *cp, sep;
519 struct cpuinfo_ia64 *c = v; 519 struct cpuinfo_ia64 *c = v;
520 unsigned long mask; 520 unsigned long mask;
521 unsigned int proc_freq; 521 unsigned long proc_freq;
522 int i; 522 int i;
523 523
524 mask = c->features; 524 mask = c->features;
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 20d76fae24e8..30dbc98bf0b3 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -700,7 +700,7 @@ int ia64_pci_legacy_read(struct pci_bus *bus, u16 port, u32 *val, u8 size)
700 */ 700 */
701int ia64_pci_legacy_write(struct pci_dev *bus, u16 port, u32 val, u8 size) 701int ia64_pci_legacy_write(struct pci_dev *bus, u16 port, u32 val, u8 size)
702{ 702{
703 int ret = 0; 703 int ret = size;
704 704
705 switch (size) { 705 switch (size) {
706 case 1: 706 case 1:
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index 4bafef83e79f..96370ec1d673 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -62,6 +62,7 @@ int dpm_runtime_suspend(struct device * dev, pm_message_t state)
62 up(&dpm_sem); 62 up(&dpm_sem);
63 return error; 63 return error;
64} 64}
65EXPORT_SYMBOL(dpm_runtime_suspend);
65 66
66 67
67#if 0 68#if 0
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c
index f36c563d72c4..9888bc151755 100644
--- a/drivers/bluetooth/bluecard_cs.c
+++ b/drivers/bluetooth/bluecard_cs.c
@@ -87,14 +87,8 @@ typedef struct bluecard_info_t {
87 87
88static void bluecard_config(dev_link_t *link); 88static void bluecard_config(dev_link_t *link);
89static void bluecard_release(dev_link_t *link); 89static void bluecard_release(dev_link_t *link);
90static int bluecard_event(event_t event, int priority, event_callback_args_t *args);
91 90
92static dev_info_t dev_info = "bluecard_cs"; 91static void bluecard_detach(struct pcmcia_device *p_dev);
93
94static dev_link_t *bluecard_attach(void);
95static void bluecard_detach(dev_link_t *);
96
97static dev_link_t *dev_list = NULL;
98 92
99 93
100/* Default baud rate: 57600, 115200, 230400 or 460800 */ 94/* Default baud rate: 57600, 115200, 230400 or 460800 */
@@ -862,17 +856,15 @@ static int bluecard_close(bluecard_info_t *info)
862 return 0; 856 return 0;
863} 857}
864 858
865static dev_link_t *bluecard_attach(void) 859static int bluecard_attach(struct pcmcia_device *p_dev)
866{ 860{
867 bluecard_info_t *info; 861 bluecard_info_t *info;
868 client_reg_t client_reg;
869 dev_link_t *link; 862 dev_link_t *link;
870 int ret;
871 863
872 /* Create new info device */ 864 /* Create new info device */
873 info = kzalloc(sizeof(*info), GFP_KERNEL); 865 info = kzalloc(sizeof(*info), GFP_KERNEL);
874 if (!info) 866 if (!info)
875 return NULL; 867 return -ENOMEM;
876 868
877 link = &info->link; 869 link = &info->link;
878 link->priv = info; 870 link->priv = info;
@@ -889,50 +881,24 @@ static dev_link_t *bluecard_attach(void)
889 link->conf.Vcc = 50; 881 link->conf.Vcc = 50;
890 link->conf.IntType = INT_MEMORY_AND_IO; 882 link->conf.IntType = INT_MEMORY_AND_IO;
891 883
892 /* Register with Card Services */ 884 link->handle = p_dev;
893 link->next = dev_list; 885 p_dev->instance = link;
894 dev_list = link;
895 client_reg.dev_info = &dev_info;
896 client_reg.Version = 0x0210;
897 client_reg.event_callback_args.client_data = link;
898
899 ret = pcmcia_register_client(&link->handle, &client_reg);
900 if (ret != CS_SUCCESS) {
901 cs_error(link->handle, RegisterClient, ret);
902 bluecard_detach(link);
903 return NULL;
904 }
905 886
906 return link; 887 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
888 bluecard_config(link);
889
890 return 0;
907} 891}
908 892
909 893
910static void bluecard_detach(dev_link_t *link) 894static void bluecard_detach(struct pcmcia_device *p_dev)
911{ 895{
896 dev_link_t *link = dev_to_instance(p_dev);
912 bluecard_info_t *info = link->priv; 897 bluecard_info_t *info = link->priv;
913 dev_link_t **linkp;
914 int ret;
915
916 /* Locate device structure */
917 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
918 if (*linkp == link)
919 break;
920
921 if (*linkp == NULL)
922 return;
923 898
924 if (link->state & DEV_CONFIG) 899 if (link->state & DEV_CONFIG)
925 bluecard_release(link); 900 bluecard_release(link);
926 901
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 */
934 *linkp = link->next;
935
936 kfree(info); 902 kfree(info);
937} 903}
938 904
@@ -1045,39 +1011,24 @@ static void bluecard_release(dev_link_t *link)
1045 link->state &= ~DEV_CONFIG; 1011 link->state &= ~DEV_CONFIG;
1046} 1012}
1047 1013
1014static int bluecard_suspend(struct pcmcia_device *dev)
1015{
1016 dev_link_t *link = dev_to_instance(dev);
1017
1018 link->state |= DEV_SUSPEND;
1019 if (link->state & DEV_CONFIG)
1020 pcmcia_release_configuration(link->handle);
1048 1021
1049static int bluecard_event(event_t event, int priority, event_callback_args_t *args) 1022 return 0;
1023}
1024
1025static int bluecard_resume(struct pcmcia_device *dev)
1050{ 1026{
1051 dev_link_t *link = args->client_data; 1027 dev_link_t *link = dev_to_instance(dev);
1052 bluecard_info_t *info = link->priv;
1053 1028
1054 switch (event) { 1029 link->state &= ~DEV_SUSPEND;
1055 case CS_EVENT_CARD_REMOVAL: 1030 if (DEV_OK(link))
1056 link->state &= ~DEV_PRESENT; 1031 pcmcia_request_configuration(link->handle, &link->conf);
1057 if (link->state & DEV_CONFIG) {
1058 bluecard_close(info);
1059 bluecard_release(link);
1060 }
1061 break;
1062 case CS_EVENT_CARD_INSERTION:
1063 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
1064 bluecard_config(link);
1065 break;
1066 case CS_EVENT_PM_SUSPEND:
1067 link->state |= DEV_SUSPEND;
1068 /* Fall through... */
1069 case CS_EVENT_RESET_PHYSICAL:
1070 if (link->state & DEV_CONFIG)
1071 pcmcia_release_configuration(link->handle);
1072 break;
1073 case CS_EVENT_PM_RESUME:
1074 link->state &= ~DEV_SUSPEND;
1075 /* Fall through... */
1076 case CS_EVENT_CARD_RESET:
1077 if (DEV_OK(link))
1078 pcmcia_request_configuration(link->handle, &link->conf);
1079 break;
1080 }
1081 1032
1082 return 0; 1033 return 0;
1083} 1034}
@@ -1095,10 +1046,11 @@ static struct pcmcia_driver bluecard_driver = {
1095 .drv = { 1046 .drv = {
1096 .name = "bluecard_cs", 1047 .name = "bluecard_cs",
1097 }, 1048 },
1098 .attach = bluecard_attach, 1049 .probe = bluecard_attach,
1099 .event = bluecard_event, 1050 .remove = bluecard_detach,
1100 .detach = bluecard_detach,
1101 .id_table = bluecard_ids, 1051 .id_table = bluecard_ids,
1052 .suspend = bluecard_suspend,
1053 .resume = bluecard_resume,
1102}; 1054};
1103 1055
1104static int __init init_bluecard_cs(void) 1056static int __init init_bluecard_cs(void)
@@ -1110,7 +1062,6 @@ static int __init init_bluecard_cs(void)
1110static void __exit exit_bluecard_cs(void) 1062static void __exit exit_bluecard_cs(void)
1111{ 1063{
1112 pcmcia_unregister_driver(&bluecard_driver); 1064 pcmcia_unregister_driver(&bluecard_driver);
1113 BUG_ON(dev_list != NULL);
1114} 1065}
1115 1066
1116module_init(init_bluecard_cs); 1067module_init(init_bluecard_cs);
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
index d2a0add19cc8..e522d19ad886 100644
--- a/drivers/bluetooth/bt3c_cs.c
+++ b/drivers/bluetooth/bt3c_cs.c
@@ -90,14 +90,8 @@ typedef struct bt3c_info_t {
90 90
91static void bt3c_config(dev_link_t *link); 91static void bt3c_config(dev_link_t *link);
92static void bt3c_release(dev_link_t *link); 92static void bt3c_release(dev_link_t *link);
93static int bt3c_event(event_t event, int priority, event_callback_args_t *args);
94 93
95static dev_info_t dev_info = "bt3c_cs"; 94static void bt3c_detach(struct pcmcia_device *p_dev);
96
97static dev_link_t *bt3c_attach(void);
98static void bt3c_detach(dev_link_t *);
99
100static dev_link_t *dev_list = NULL;
101 95
102 96
103/* Transmit states */ 97/* Transmit states */
@@ -663,17 +657,15 @@ static int bt3c_close(bt3c_info_t *info)
663 return 0; 657 return 0;
664} 658}
665 659
666static dev_link_t *bt3c_attach(void) 660static int bt3c_attach(struct pcmcia_device *p_dev)
667{ 661{
668 bt3c_info_t *info; 662 bt3c_info_t *info;
669 client_reg_t client_reg;
670 dev_link_t *link; 663 dev_link_t *link;
671 int ret;
672 664
673 /* Create new info device */ 665 /* Create new info device */
674 info = kzalloc(sizeof(*info), GFP_KERNEL); 666 info = kzalloc(sizeof(*info), GFP_KERNEL);
675 if (!info) 667 if (!info)
676 return NULL; 668 return -ENOMEM;
677 669
678 link = &info->link; 670 link = &info->link;
679 link->priv = info; 671 link->priv = info;
@@ -690,50 +682,24 @@ static dev_link_t *bt3c_attach(void)
690 link->conf.Vcc = 50; 682 link->conf.Vcc = 50;
691 link->conf.IntType = INT_MEMORY_AND_IO; 683 link->conf.IntType = INT_MEMORY_AND_IO;
692 684
693 /* Register with Card Services */ 685 link->handle = p_dev;
694 link->next = dev_list; 686 p_dev->instance = link;
695 dev_list = link;
696 client_reg.dev_info = &dev_info;
697 client_reg.Version = 0x0210;
698 client_reg.event_callback_args.client_data = link;
699
700 ret = pcmcia_register_client(&link->handle, &client_reg);
701 if (ret != CS_SUCCESS) {
702 cs_error(link->handle, RegisterClient, ret);
703 bt3c_detach(link);
704 return NULL;
705 }
706 687
707 return link; 688 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
689 bt3c_config(link);
690
691 return 0;
708} 692}
709 693
710 694
711static void bt3c_detach(dev_link_t *link) 695static void bt3c_detach(struct pcmcia_device *p_dev)
712{ 696{
697 dev_link_t *link = dev_to_instance(p_dev);
713 bt3c_info_t *info = link->priv; 698 bt3c_info_t *info = link->priv;
714 dev_link_t **linkp;
715 int ret;
716
717 /* Locate device structure */
718 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
719 if (*linkp == link)
720 break;
721
722 if (*linkp == NULL)
723 return;
724 699
725 if (link->state & DEV_CONFIG) 700 if (link->state & DEV_CONFIG)
726 bt3c_release(link); 701 bt3c_release(link);
727 702
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 */
735 *linkp = link->next;
736
737 kfree(info); 703 kfree(info);
738} 704}
739 705
@@ -891,43 +857,29 @@ static void bt3c_release(dev_link_t *link)
891 link->state &= ~DEV_CONFIG; 857 link->state &= ~DEV_CONFIG;
892} 858}
893 859
860static int bt3c_suspend(struct pcmcia_device *dev)
861{
862 dev_link_t *link = dev_to_instance(dev);
894 863
895static int bt3c_event(event_t event, int priority, event_callback_args_t *args) 864 link->state |= DEV_SUSPEND;
865 if (link->state & DEV_CONFIG)
866 pcmcia_release_configuration(link->handle);
867
868 return 0;
869}
870
871static int bt3c_resume(struct pcmcia_device *dev)
896{ 872{
897 dev_link_t *link = args->client_data; 873 dev_link_t *link = dev_to_instance(dev);
898 bt3c_info_t *info = link->priv;
899 874
900 switch (event) { 875 link->state &= ~DEV_SUSPEND;
901 case CS_EVENT_CARD_REMOVAL: 876 if (DEV_OK(link))
902 link->state &= ~DEV_PRESENT; 877 pcmcia_request_configuration(link->handle, &link->conf);
903 if (link->state & DEV_CONFIG) {
904 bt3c_close(info);
905 bt3c_release(link);
906 }
907 break;
908 case CS_EVENT_CARD_INSERTION:
909 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
910 bt3c_config(link);
911 break;
912 case CS_EVENT_PM_SUSPEND:
913 link->state |= DEV_SUSPEND;
914 /* Fall through... */
915 case CS_EVENT_RESET_PHYSICAL:
916 if (link->state & DEV_CONFIG)
917 pcmcia_release_configuration(link->handle);
918 break;
919 case CS_EVENT_PM_RESUME:
920 link->state &= ~DEV_SUSPEND;
921 /* Fall through... */
922 case CS_EVENT_CARD_RESET:
923 if (DEV_OK(link))
924 pcmcia_request_configuration(link->handle, &link->conf);
925 break;
926 }
927 878
928 return 0; 879 return 0;
929} 880}
930 881
882
931static struct pcmcia_device_id bt3c_ids[] = { 883static struct pcmcia_device_id bt3c_ids[] = {
932 PCMCIA_DEVICE_PROD_ID13("3COM", "Bluetooth PC Card", 0xefce0a31, 0xd4ce9b02), 884 PCMCIA_DEVICE_PROD_ID13("3COM", "Bluetooth PC Card", 0xefce0a31, 0xd4ce9b02),
933 PCMCIA_DEVICE_NULL 885 PCMCIA_DEVICE_NULL
@@ -939,10 +891,11 @@ static struct pcmcia_driver bt3c_driver = {
939 .drv = { 891 .drv = {
940 .name = "bt3c_cs", 892 .name = "bt3c_cs",
941 }, 893 },
942 .attach = bt3c_attach, 894 .probe = bt3c_attach,
943 .event = bt3c_event, 895 .remove = bt3c_detach,
944 .detach = bt3c_detach,
945 .id_table = bt3c_ids, 896 .id_table = bt3c_ids,
897 .suspend = bt3c_suspend,
898 .resume = bt3c_resume,
946}; 899};
947 900
948static int __init init_bt3c_cs(void) 901static int __init init_bt3c_cs(void)
@@ -954,7 +907,6 @@ static int __init init_bt3c_cs(void)
954static void __exit exit_bt3c_cs(void) 907static void __exit exit_bt3c_cs(void)
955{ 908{
956 pcmcia_unregister_driver(&bt3c_driver); 909 pcmcia_unregister_driver(&bt3c_driver);
957 BUG_ON(dev_list != NULL);
958} 910}
959 911
960module_init(init_bt3c_cs); 912module_init(init_bt3c_cs);
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c
index 529a28a3209d..7b4bff4cfa2d 100644
--- a/drivers/bluetooth/btuart_cs.c
+++ b/drivers/bluetooth/btuart_cs.c
@@ -86,14 +86,8 @@ typedef struct btuart_info_t {
86 86
87static void btuart_config(dev_link_t *link); 87static void btuart_config(dev_link_t *link);
88static void btuart_release(dev_link_t *link); 88static void btuart_release(dev_link_t *link);
89static int btuart_event(event_t event, int priority, event_callback_args_t *args);
90 89
91static dev_info_t dev_info = "btuart_cs"; 90static void btuart_detach(struct pcmcia_device *p_dev);
92
93static dev_link_t *btuart_attach(void);
94static void btuart_detach(dev_link_t *);
95
96static dev_link_t *dev_list = NULL;
97 91
98 92
99/* Maximum baud rate */ 93/* Maximum baud rate */
@@ -582,17 +576,15 @@ static int btuart_close(btuart_info_t *info)
582 return 0; 576 return 0;
583} 577}
584 578
585static dev_link_t *btuart_attach(void) 579static int btuart_attach(struct pcmcia_device *p_dev)
586{ 580{
587 btuart_info_t *info; 581 btuart_info_t *info;
588 client_reg_t client_reg;
589 dev_link_t *link; 582 dev_link_t *link;
590 int ret;
591 583
592 /* Create new info device */ 584 /* Create new info device */
593 info = kzalloc(sizeof(*info), GFP_KERNEL); 585 info = kzalloc(sizeof(*info), GFP_KERNEL);
594 if (!info) 586 if (!info)
595 return NULL; 587 return -ENOMEM;
596 588
597 link = &info->link; 589 link = &info->link;
598 link->priv = info; 590 link->priv = info;
@@ -609,50 +601,24 @@ static dev_link_t *btuart_attach(void)
609 link->conf.Vcc = 50; 601 link->conf.Vcc = 50;
610 link->conf.IntType = INT_MEMORY_AND_IO; 602 link->conf.IntType = INT_MEMORY_AND_IO;
611 603
612 /* Register with Card Services */ 604 link->handle = p_dev;
613 link->next = dev_list; 605 p_dev->instance = link;
614 dev_list = link;
615 client_reg.dev_info = &dev_info;
616 client_reg.Version = 0x0210;
617 client_reg.event_callback_args.client_data = link;
618
619 ret = pcmcia_register_client(&link->handle, &client_reg);
620 if (ret != CS_SUCCESS) {
621 cs_error(link->handle, RegisterClient, ret);
622 btuart_detach(link);
623 return NULL;
624 }
625 606
626 return link; 607 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
608 btuart_config(link);
609
610 return 0;
627} 611}
628 612
629 613
630static void btuart_detach(dev_link_t *link) 614static void btuart_detach(struct pcmcia_device *p_dev)
631{ 615{
616 dev_link_t *link = dev_to_instance(p_dev);
632 btuart_info_t *info = link->priv; 617 btuart_info_t *info = link->priv;
633 dev_link_t **linkp;
634 int ret;
635
636 /* Locate device structure */
637 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
638 if (*linkp == link)
639 break;
640
641 if (*linkp == NULL)
642 return;
643 618
644 if (link->state & DEV_CONFIG) 619 if (link->state & DEV_CONFIG)
645 btuart_release(link); 620 btuart_release(link);
646 621
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 */
654 *linkp = link->next;
655
656 kfree(info); 622 kfree(info);
657} 623}
658 624
@@ -811,43 +777,29 @@ static void btuart_release(dev_link_t *link)
811 link->state &= ~DEV_CONFIG; 777 link->state &= ~DEV_CONFIG;
812} 778}
813 779
780static int btuart_suspend(struct pcmcia_device *dev)
781{
782 dev_link_t *link = dev_to_instance(dev);
814 783
815static int btuart_event(event_t event, int priority, event_callback_args_t *args) 784 link->state |= DEV_SUSPEND;
785 if (link->state & DEV_CONFIG)
786 pcmcia_release_configuration(link->handle);
787
788 return 0;
789}
790
791static int btuart_resume(struct pcmcia_device *dev)
816{ 792{
817 dev_link_t *link = args->client_data; 793 dev_link_t *link = dev_to_instance(dev);
818 btuart_info_t *info = link->priv;
819 794
820 switch (event) { 795 link->state &= ~DEV_SUSPEND;
821 case CS_EVENT_CARD_REMOVAL: 796 if (DEV_OK(link))
822 link->state &= ~DEV_PRESENT; 797 pcmcia_request_configuration(link->handle, &link->conf);
823 if (link->state & DEV_CONFIG) {
824 btuart_close(info);
825 btuart_release(link);
826 }
827 break;
828 case CS_EVENT_CARD_INSERTION:
829 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
830 btuart_config(link);
831 break;
832 case CS_EVENT_PM_SUSPEND:
833 link->state |= DEV_SUSPEND;
834 /* Fall through... */
835 case CS_EVENT_RESET_PHYSICAL:
836 if (link->state & DEV_CONFIG)
837 pcmcia_release_configuration(link->handle);
838 break;
839 case CS_EVENT_PM_RESUME:
840 link->state &= ~DEV_SUSPEND;
841 /* Fall through... */
842 case CS_EVENT_CARD_RESET:
843 if (DEV_OK(link))
844 pcmcia_request_configuration(link->handle, &link->conf);
845 break;
846 }
847 798
848 return 0; 799 return 0;
849} 800}
850 801
802
851static struct pcmcia_device_id btuart_ids[] = { 803static struct pcmcia_device_id btuart_ids[] = {
852 /* don't use this driver. Use serial_cs + hci_uart instead */ 804 /* don't use this driver. Use serial_cs + hci_uart instead */
853 PCMCIA_DEVICE_NULL 805 PCMCIA_DEVICE_NULL
@@ -859,10 +811,11 @@ static struct pcmcia_driver btuart_driver = {
859 .drv = { 811 .drv = {
860 .name = "btuart_cs", 812 .name = "btuart_cs",
861 }, 813 },
862 .attach = btuart_attach, 814 .probe = btuart_attach,
863 .event = btuart_event, 815 .remove = btuart_detach,
864 .detach = btuart_detach,
865 .id_table = btuart_ids, 816 .id_table = btuart_ids,
817 .suspend = btuart_suspend,
818 .resume = btuart_resume,
866}; 819};
867 820
868static int __init init_btuart_cs(void) 821static int __init init_btuart_cs(void)
@@ -874,7 +827,6 @@ static int __init init_btuart_cs(void)
874static void __exit exit_btuart_cs(void) 827static void __exit exit_btuart_cs(void)
875{ 828{
876 pcmcia_unregister_driver(&btuart_driver); 829 pcmcia_unregister_driver(&btuart_driver);
877 BUG_ON(dev_list != NULL);
878} 830}
879 831
880module_init(init_btuart_cs); 832module_init(init_btuart_cs);
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c
index dec5980a1cd6..0449bc45ae5e 100644
--- a/drivers/bluetooth/dtl1_cs.c
+++ b/drivers/bluetooth/dtl1_cs.c
@@ -89,14 +89,8 @@ typedef struct dtl1_info_t {
89 89
90static void dtl1_config(dev_link_t *link); 90static void dtl1_config(dev_link_t *link);
91static void dtl1_release(dev_link_t *link); 91static void dtl1_release(dev_link_t *link);
92static int dtl1_event(event_t event, int priority, event_callback_args_t *args);
93 92
94static dev_info_t dev_info = "dtl1_cs"; 93static void dtl1_detach(struct pcmcia_device *p_dev);
95
96static dev_link_t *dtl1_attach(void);
97static void dtl1_detach(dev_link_t *);
98
99static dev_link_t *dev_list = NULL;
100 94
101 95
102/* Transmit states */ 96/* Transmit states */
@@ -561,17 +555,15 @@ static int dtl1_close(dtl1_info_t *info)
561 return 0; 555 return 0;
562} 556}
563 557
564static dev_link_t *dtl1_attach(void) 558static int dtl1_attach(struct pcmcia_device *p_dev)
565{ 559{
566 dtl1_info_t *info; 560 dtl1_info_t *info;
567 client_reg_t client_reg;
568 dev_link_t *link; 561 dev_link_t *link;
569 int ret;
570 562
571 /* Create new info device */ 563 /* Create new info device */
572 info = kzalloc(sizeof(*info), GFP_KERNEL); 564 info = kzalloc(sizeof(*info), GFP_KERNEL);
573 if (!info) 565 if (!info)
574 return NULL; 566 return -ENOMEM;
575 567
576 link = &info->link; 568 link = &info->link;
577 link->priv = info; 569 link->priv = info;
@@ -588,50 +580,24 @@ static dev_link_t *dtl1_attach(void)
588 link->conf.Vcc = 50; 580 link->conf.Vcc = 50;
589 link->conf.IntType = INT_MEMORY_AND_IO; 581 link->conf.IntType = INT_MEMORY_AND_IO;
590 582
591 /* Register with Card Services */ 583 link->handle = p_dev;
592 link->next = dev_list; 584 p_dev->instance = link;
593 dev_list = link;
594 client_reg.dev_info = &dev_info;
595 client_reg.Version = 0x0210;
596 client_reg.event_callback_args.client_data = link;
597
598 ret = pcmcia_register_client(&link->handle, &client_reg);
599 if (ret != CS_SUCCESS) {
600 cs_error(link->handle, RegisterClient, ret);
601 dtl1_detach(link);
602 return NULL;
603 }
604 585
605 return link; 586 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
587 dtl1_config(link);
588
589 return 0;
606} 590}
607 591
608 592
609static void dtl1_detach(dev_link_t *link) 593static void dtl1_detach(struct pcmcia_device *p_dev)
610{ 594{
595 dev_link_t *link = dev_to_instance(p_dev);
611 dtl1_info_t *info = link->priv; 596 dtl1_info_t *info = link->priv;
612 dev_link_t **linkp;
613 int ret;
614
615 /* Locate device structure */
616 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
617 if (*linkp == link)
618 break;
619
620 if (*linkp == NULL)
621 return;
622 597
623 if (link->state & DEV_CONFIG) 598 if (link->state & DEV_CONFIG)
624 dtl1_release(link); 599 dtl1_release(link);
625 600
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 */
633 *linkp = link->next;
634
635 kfree(info); 601 kfree(info);
636} 602}
637 603
@@ -763,46 +729,33 @@ static void dtl1_release(dev_link_t *link)
763 link->state &= ~DEV_CONFIG; 729 link->state &= ~DEV_CONFIG;
764} 730}
765 731
732static int dtl1_suspend(struct pcmcia_device *dev)
733{
734 dev_link_t *link = dev_to_instance(dev);
766 735
767static int dtl1_event(event_t event, int priority, event_callback_args_t *args) 736 link->state |= DEV_SUSPEND;
737 if (link->state & DEV_CONFIG)
738 pcmcia_release_configuration(link->handle);
739
740 return 0;
741}
742
743static int dtl1_resume(struct pcmcia_device *dev)
768{ 744{
769 dev_link_t *link = args->client_data; 745 dev_link_t *link = dev_to_instance(dev);
770 dtl1_info_t *info = link->priv;
771 746
772 switch (event) { 747 link->state &= ~DEV_SUSPEND;
773 case CS_EVENT_CARD_REMOVAL: 748 if (DEV_OK(link))
774 link->state &= ~DEV_PRESENT; 749 pcmcia_request_configuration(link->handle, &link->conf);
775 if (link->state & DEV_CONFIG) {
776 dtl1_close(info);
777 dtl1_release(link);
778 }
779 break;
780 case CS_EVENT_CARD_INSERTION:
781 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
782 dtl1_config(link);
783 break;
784 case CS_EVENT_PM_SUSPEND:
785 link->state |= DEV_SUSPEND;
786 /* Fall through... */
787 case CS_EVENT_RESET_PHYSICAL:
788 if (link->state & DEV_CONFIG)
789 pcmcia_release_configuration(link->handle);
790 break;
791 case CS_EVENT_PM_RESUME:
792 link->state &= ~DEV_SUSPEND;
793 /* Fall through... */
794 case CS_EVENT_CARD_RESET:
795 if (DEV_OK(link))
796 pcmcia_request_configuration(link->handle, &link->conf);
797 break;
798 }
799 750
800 return 0; 751 return 0;
801} 752}
802 753
754
803static struct pcmcia_device_id dtl1_ids[] = { 755static struct pcmcia_device_id dtl1_ids[] = {
804 PCMCIA_DEVICE_PROD_ID12("Nokia Mobile Phones", "DTL-1", 0xe1bfdd64, 0xe168480d), 756 PCMCIA_DEVICE_PROD_ID12("Nokia Mobile Phones", "DTL-1", 0xe1bfdd64, 0xe168480d),
805 PCMCIA_DEVICE_PROD_ID12("Socket", "CF", 0xb38bcc2e, 0x44ebf863), 757 PCMCIA_DEVICE_PROD_ID12("Socket", "CF", 0xb38bcc2e, 0x44ebf863),
758 PCMCIA_DEVICE_PROD_ID12("Socket", "CF+ Personal Network Card", 0xb38bcc2e, 0xe732bae3),
806 PCMCIA_DEVICE_NULL 759 PCMCIA_DEVICE_NULL
807}; 760};
808MODULE_DEVICE_TABLE(pcmcia, dtl1_ids); 761MODULE_DEVICE_TABLE(pcmcia, dtl1_ids);
@@ -812,10 +765,11 @@ static struct pcmcia_driver dtl1_driver = {
812 .drv = { 765 .drv = {
813 .name = "dtl1_cs", 766 .name = "dtl1_cs",
814 }, 767 },
815 .attach = dtl1_attach, 768 .probe = dtl1_attach,
816 .event = dtl1_event, 769 .remove = dtl1_detach,
817 .detach = dtl1_detach,
818 .id_table = dtl1_ids, 770 .id_table = dtl1_ids,
771 .suspend = dtl1_suspend,
772 .resume = dtl1_resume,
819}; 773};
820 774
821static int __init init_dtl1_cs(void) 775static int __init init_dtl1_cs(void)
@@ -827,7 +781,6 @@ static int __init init_dtl1_cs(void)
827static void __exit exit_dtl1_cs(void) 781static void __exit exit_dtl1_cs(void)
828{ 782{
829 pcmcia_unregister_driver(&dtl1_driver); 783 pcmcia_unregister_driver(&dtl1_driver);
830 BUG_ON(dev_list != NULL);
831} 784}
832 785
833module_init(init_dtl1_cs); 786module_init(init_dtl1_cs);
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c
index 61681c9f3f72..649677b5dc36 100644
--- a/drivers/char/pcmcia/cm4000_cs.c
+++ b/drivers/char/pcmcia/cm4000_cs.c
@@ -66,7 +66,6 @@ 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);
70static void cm4000_release(dev_link_t *link); 69static void cm4000_release(dev_link_t *link);
71 70
72static int major; /* major number we get from the kernel */ 71static int major; /* major number we get from the kernel */
@@ -156,7 +155,6 @@ struct cm4000_dev {
156 /*sbuf*/ 512*sizeof(char) - \ 155 /*sbuf*/ 512*sizeof(char) - \
157 /*queue*/ 4*sizeof(wait_queue_head_t)) 156 /*queue*/ 4*sizeof(wait_queue_head_t))
158 157
159static dev_info_t dev_info = MODULE_NAME;
160static dev_link_t *dev_table[CM4000_MAX_DEV]; 158static dev_link_t *dev_table[CM4000_MAX_DEV];
161 159
162/* This table doesn't use spaces after the comma between fields and thus 160/* This table doesn't use spaces after the comma between fields and thus
@@ -1864,68 +1862,36 @@ cs_release:
1864 link->state &= ~DEV_CONFIG_PENDING; 1862 link->state &= ~DEV_CONFIG_PENDING;
1865} 1863}
1866 1864
1867static int cm4000_event(event_t event, int priority, 1865static int cm4000_suspend(struct pcmcia_device *p_dev)
1868 event_callback_args_t *args)
1869{ 1866{
1870 dev_link_t *link; 1867 dev_link_t *link = dev_to_instance(p_dev);
1871 struct cm4000_dev *dev; 1868 struct cm4000_dev *dev;
1872 int devno;
1873 1869
1874 link = args->client_data;
1875 dev = link->priv; 1870 dev = link->priv;
1876 1871
1877 DEBUGP(3, dev, "-> cm4000_event\n"); 1872 link->state |= DEV_SUSPEND;
1878 for (devno = 0; devno < CM4000_MAX_DEV; devno++) 1873 if (link->state & DEV_CONFIG)
1879 if (dev_table[devno] == link) 1874 pcmcia_release_configuration(link->handle);
1880 break; 1875 stop_monitor(dev);
1881 1876
1882 if (devno == CM4000_MAX_DEV) 1877 return 0;
1883 return CS_BAD_ADAPTER; 1878}
1884 1879
1885 switch (event) { 1880static int cm4000_resume(struct pcmcia_device *p_dev)
1886 case CS_EVENT_CARD_INSERTION: 1881{
1887 DEBUGP(5, dev, "CS_EVENT_CARD_INSERTION\n"); 1882 dev_link_t *link = dev_to_instance(p_dev);
1888 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 1883 struct cm4000_dev *dev;
1889 cm4000_config(link, devno); 1884
1890 break; 1885 dev = link->priv;
1891 case CS_EVENT_CARD_REMOVAL: 1886
1892 DEBUGP(5, dev, "CS_EVENT_CARD_REMOVAL\n"); 1887 link->state &= ~DEV_SUSPEND;
1893 link->state &= ~DEV_PRESENT; 1888 if (link->state & DEV_CONFIG)
1894 stop_monitor(dev); 1889 pcmcia_request_configuration(link->handle, &link->conf);
1895 break; 1890
1896 case CS_EVENT_PM_SUSPEND: 1891 if (link->open)
1897 DEBUGP(5, dev, "CS_EVENT_PM_SUSPEND " 1892 start_monitor(dev);
1898 "(fall-through to CS_EVENT_RESET_PHYSICAL)\n"); 1893
1899 link->state |= DEV_SUSPEND; 1894 return 0;
1900 /* fall-through */
1901 case CS_EVENT_RESET_PHYSICAL:
1902 DEBUGP(5, dev, "CS_EVENT_RESET_PHYSICAL\n");
1903 if (link->state & DEV_CONFIG) {
1904 DEBUGP(5, dev, "ReleaseConfiguration\n");
1905 pcmcia_release_configuration(link->handle);
1906 }
1907 stop_monitor(dev);
1908 break;
1909 case CS_EVENT_PM_RESUME:
1910 DEBUGP(5, dev, "CS_EVENT_PM_RESUME "
1911 "(fall-through to CS_EVENT_CARD_RESET)\n");
1912 link->state &= ~DEV_SUSPEND;
1913 /* fall-through */
1914 case CS_EVENT_CARD_RESET:
1915 DEBUGP(5, dev, "CS_EVENT_CARD_RESET\n");
1916 if ((link->state & DEV_CONFIG)) {
1917 DEBUGP(5, dev, "RequestConfiguration\n");
1918 pcmcia_request_configuration(link->handle, &link->conf);
1919 }
1920 if (link->open)
1921 start_monitor(dev);
1922 break;
1923 default:
1924 DEBUGP(5, dev, "unknown event %.2x\n", event);
1925 break;
1926 }
1927 DEBUGP(3, dev, "<- cm4000_event\n");
1928 return CS_SUCCESS;
1929} 1895}
1930 1896
1931static void cm4000_release(dev_link_t *link) 1897static void cm4000_release(dev_link_t *link)
@@ -1935,11 +1901,10 @@ static void cm4000_release(dev_link_t *link)
1935 pcmcia_release_io(link->handle, &link->io); 1901 pcmcia_release_io(link->handle, &link->io);
1936} 1902}
1937 1903
1938static dev_link_t *cm4000_attach(void) 1904static int cm4000_attach(struct pcmcia_device *p_dev)
1939{ 1905{
1940 struct cm4000_dev *dev; 1906 struct cm4000_dev *dev;
1941 dev_link_t *link; 1907 dev_link_t *link;
1942 client_reg_t client_reg;
1943 int i; 1908 int i;
1944 1909
1945 for (i = 0; i < CM4000_MAX_DEV; i++) 1910 for (i = 0; i < CM4000_MAX_DEV; i++)
@@ -1948,76 +1913,55 @@ static dev_link_t *cm4000_attach(void)
1948 1913
1949 if (i == CM4000_MAX_DEV) { 1914 if (i == CM4000_MAX_DEV) {
1950 printk(KERN_NOTICE MODULE_NAME ": all devices in use\n"); 1915 printk(KERN_NOTICE MODULE_NAME ": all devices in use\n");
1951 return NULL; 1916 return -ENODEV;
1952 } 1917 }
1953 1918
1954 /* create a new cm4000_cs device */ 1919 /* create a new cm4000_cs device */
1955 dev = kzalloc(sizeof(struct cm4000_dev), GFP_KERNEL); 1920 dev = kzalloc(sizeof(struct cm4000_dev), GFP_KERNEL);
1956 if (dev == NULL) 1921 if (dev == NULL)
1957 return NULL; 1922 return -ENOMEM;
1958 1923
1959 link = &dev->link; 1924 link = &dev->link;
1960 link->priv = dev; 1925 link->priv = dev;
1961 link->conf.IntType = INT_MEMORY_AND_IO; 1926 link->conf.IntType = INT_MEMORY_AND_IO;
1962 dev_table[i] = link; 1927 dev_table[i] = link;
1963 1928
1964 /* register with card services */
1965 client_reg.dev_info = &dev_info;
1966 client_reg.EventMask =
1967 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
1968 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
1969 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
1970 client_reg.Version = 0x0210;
1971 client_reg.event_callback_args.client_data = link;
1972
1973 i = pcmcia_register_client(&link->handle, &client_reg);
1974 if (i) {
1975 cs_error(link->handle, RegisterClient, i);
1976 cm4000_detach(link);
1977 return NULL;
1978 }
1979
1980 init_waitqueue_head(&dev->devq); 1929 init_waitqueue_head(&dev->devq);
1981 init_waitqueue_head(&dev->ioq); 1930 init_waitqueue_head(&dev->ioq);
1982 init_waitqueue_head(&dev->atrq); 1931 init_waitqueue_head(&dev->atrq);
1983 init_waitqueue_head(&dev->readq); 1932 init_waitqueue_head(&dev->readq);
1984 1933
1985 return link; 1934 link->handle = p_dev;
1986} 1935 p_dev->instance = link;
1987
1988static void cm4000_detach_by_devno(int devno, dev_link_t * link)
1989{
1990 struct cm4000_dev *dev = link->priv;
1991
1992 DEBUGP(3, dev, "-> detach_by_devno(devno=%d)\n", devno);
1993
1994 if (link->state & DEV_CONFIG) {
1995 DEBUGP(5, dev, "device still configured (try to release it)\n");
1996 cm4000_release(link);
1997 }
1998 1936
1999 if (link->handle) { 1937 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
2000 pcmcia_deregister_client(link->handle); 1938 cm4000_config(link, i);
2001 }
2002 1939
2003 dev_table[devno] = NULL; 1940 return 0;
2004 kfree(dev);
2005 return;
2006} 1941}
2007 1942
2008static void cm4000_detach(dev_link_t * link) 1943static void cm4000_detach(struct pcmcia_device *p_dev)
2009{ 1944{
2010 int i; 1945 dev_link_t *link = dev_to_instance(p_dev);
1946 struct cm4000_dev *dev = link->priv;
1947 int devno;
2011 1948
2012 /* find device */ 1949 /* find device */
2013 for (i = 0; i < CM4000_MAX_DEV; i++) 1950 for (devno = 0; devno < CM4000_MAX_DEV; devno++)
2014 if (dev_table[i] == link) 1951 if (dev_table[devno] == link)
2015 break; 1952 break;
2016 1953 if (devno == CM4000_MAX_DEV)
2017 if (i == CM4000_MAX_DEV)
2018 return; 1954 return;
2019 1955
2020 cm4000_detach_by_devno(i, link); 1956 link->state &= ~DEV_PRESENT;
1957 stop_monitor(dev);
1958
1959 if (link->state & DEV_CONFIG)
1960 cm4000_release(link);
1961
1962 dev_table[devno] = NULL;
1963 kfree(dev);
1964
2021 return; 1965 return;
2022} 1966}
2023 1967
@@ -2042,9 +1986,10 @@ static struct pcmcia_driver cm4000_driver = {
2042 .drv = { 1986 .drv = {
2043 .name = "cm4000_cs", 1987 .name = "cm4000_cs",
2044 }, 1988 },
2045 .attach = cm4000_attach, 1989 .probe = cm4000_attach,
2046 .detach = cm4000_detach, 1990 .remove = cm4000_detach,
2047 .event = cm4000_event, 1991 .suspend = cm4000_suspend,
1992 .resume = cm4000_resume,
2048 .id_table = cm4000_ids, 1993 .id_table = cm4000_ids,
2049}; 1994};
2050 1995
@@ -2064,13 +2009,8 @@ static int __init cmm_init(void)
2064 2009
2065static void __exit cmm_exit(void) 2010static void __exit cmm_exit(void)
2066{ 2011{
2067 int i;
2068
2069 printk(KERN_INFO MODULE_NAME ": unloading\n"); 2012 printk(KERN_INFO MODULE_NAME ": unloading\n");
2070 pcmcia_unregister_driver(&cm4000_driver); 2013 pcmcia_unregister_driver(&cm4000_driver);
2071 for (i = 0; i < CM4000_MAX_DEV; i++)
2072 if (dev_table[i])
2073 cm4000_detach_by_devno(i, dev_table[i]);
2074 unregister_chrdev(major, DEVICE_NAME); 2014 unregister_chrdev(major, DEVICE_NAME);
2075}; 2015};
2076 2016
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c
index 4c698d908ffa..46eb371bf17e 100644
--- a/drivers/char/pcmcia/cm4040_cs.c
+++ b/drivers/char/pcmcia/cm4040_cs.c
@@ -65,7 +65,6 @@ static char *version =
65#define POLL_PERIOD msecs_to_jiffies(10) 65#define POLL_PERIOD msecs_to_jiffies(10)
66 66
67static void reader_release(dev_link_t *link); 67static void reader_release(dev_link_t *link);
68static void reader_detach(dev_link_t *link);
69 68
70static int major; 69static int major;
71 70
@@ -86,7 +85,6 @@ struct reader_dev {
86 struct timer_list poll_timer; 85 struct timer_list poll_timer;
87}; 86};
88 87
89static dev_info_t dev_info = MODULE_NAME;
90static dev_link_t *dev_table[CM_MAX_DEV]; 88static dev_link_t *dev_table[CM_MAX_DEV];
91 89
92#ifndef PCMCIA_DEBUG 90#ifndef PCMCIA_DEBUG
@@ -629,65 +627,26 @@ cs_release:
629 link->state &= ~DEV_CONFIG_PENDING; 627 link->state &= ~DEV_CONFIG_PENDING;
630} 628}
631 629
632static int reader_event(event_t event, int priority, 630static int reader_suspend(struct pcmcia_device *p_dev)
633 event_callback_args_t *args)
634{ 631{
635 dev_link_t *link; 632 dev_link_t *link = dev_to_instance(p_dev);
636 struct reader_dev *dev;
637 int devno;
638 633
639 link = args->client_data; 634 link->state |= DEV_SUSPEND;
640 dev = link->priv; 635 if (link->state & DEV_CONFIG)
641 DEBUGP(3, dev, "-> reader_event\n"); 636 pcmcia_release_configuration(link->handle);
642 for (devno = 0; devno < CM_MAX_DEV; devno++) {
643 if (dev_table[devno] == link)
644 break;
645 }
646 if (devno == CM_MAX_DEV)
647 return CS_BAD_ADAPTER;
648 637
649 switch (event) { 638 return 0;
650 case CS_EVENT_CARD_INSERTION: 639}
651 DEBUGP(5, dev, "CS_EVENT_CARD_INSERTION\n"); 640
652 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 641static int reader_resume(struct pcmcia_device *p_dev)
653 reader_config(link, devno); 642{
654 break; 643 dev_link_t *link = dev_to_instance(p_dev);
655 case CS_EVENT_CARD_REMOVAL: 644
656 DEBUGP(5, dev, "CS_EVENT_CARD_REMOVAL\n"); 645 link->state &= ~DEV_SUSPEND;
657 link->state &= ~DEV_PRESENT; 646 if (link->state & DEV_CONFIG)
658 break; 647 pcmcia_request_configuration(link->handle, &link->conf);
659 case CS_EVENT_PM_SUSPEND: 648
660 DEBUGP(5, dev, "CS_EVENT_PM_SUSPEND " 649 return 0;
661 "(fall-through to CS_EVENT_RESET_PHYSICAL)\n");
662 link->state |= DEV_SUSPEND;
663
664 case CS_EVENT_RESET_PHYSICAL:
665 DEBUGP(5, dev, "CS_EVENT_RESET_PHYSICAL\n");
666 if (link->state & DEV_CONFIG) {
667 DEBUGP(5, dev, "ReleaseConfiguration\n");
668 pcmcia_release_configuration(link->handle);
669 }
670 break;
671 case CS_EVENT_PM_RESUME:
672 DEBUGP(5, dev, "CS_EVENT_PM_RESUME "
673 "(fall-through to CS_EVENT_CARD_RESET)\n");
674 link->state &= ~DEV_SUSPEND;
675
676 case CS_EVENT_CARD_RESET:
677 DEBUGP(5, dev, "CS_EVENT_CARD_RESET\n");
678 if ((link->state & DEV_CONFIG)) {
679 DEBUGP(5, dev, "RequestConfiguration\n");
680 pcmcia_request_configuration(link->handle,
681 &link->conf);
682 }
683 break;
684 default:
685 DEBUGP(5, dev, "reader_event: unknown event %.2x\n",
686 event);
687 break;
688 }
689 DEBUGP(3, dev, "<- reader_event\n");
690 return CS_SUCCESS;
691} 650}
692 651
693static void reader_release(dev_link_t *link) 652static void reader_release(dev_link_t *link)
@@ -697,11 +656,10 @@ static void reader_release(dev_link_t *link)
697 pcmcia_release_io(link->handle, &link->io); 656 pcmcia_release_io(link->handle, &link->io);
698} 657}
699 658
700static dev_link_t *reader_attach(void) 659static int reader_attach(struct pcmcia_device *p_dev)
701{ 660{
702 struct reader_dev *dev; 661 struct reader_dev *dev;
703 dev_link_t *link; 662 dev_link_t *link;
704 client_reg_t client_reg;
705 int i; 663 int i;
706 664
707 for (i = 0; i < CM_MAX_DEV; i++) { 665 for (i = 0; i < CM_MAX_DEV; i++) {
@@ -710,11 +668,11 @@ static dev_link_t *reader_attach(void)
710 } 668 }
711 669
712 if (i == CM_MAX_DEV) 670 if (i == CM_MAX_DEV)
713 return NULL; 671 return -ENODEV;
714 672
715 dev = kzalloc(sizeof(struct reader_dev), GFP_KERNEL); 673 dev = kzalloc(sizeof(struct reader_dev), GFP_KERNEL);
716 if (dev == NULL) 674 if (dev == NULL)
717 return NULL; 675 return -ENOMEM;
718 676
719 dev->timeout = CCID_DRIVER_MINIMUM_TIMEOUT; 677 dev->timeout = CCID_DRIVER_MINIMUM_TIMEOUT;
720 dev->buffer_status = 0; 678 dev->buffer_status = 0;
@@ -725,20 +683,6 @@ static dev_link_t *reader_attach(void)
725 link->conf.IntType = INT_MEMORY_AND_IO; 683 link->conf.IntType = INT_MEMORY_AND_IO;
726 dev_table[i] = link; 684 dev_table[i] = link;
727 685
728 client_reg.dev_info = &dev_info;
729 client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
730 client_reg.EventMask=
731 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
732 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
733 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
734 client_reg.Version = 0x0210;
735 client_reg.event_callback_args.client_data = link;
736 i = pcmcia_register_client(&link->handle, &client_reg);
737 if (i) {
738 cs_error(link->handle, RegisterClient, i);
739 reader_detach(link);
740 return NULL;
741 }
742 init_waitqueue_head(&dev->devq); 686 init_waitqueue_head(&dev->devq);
743 init_waitqueue_head(&dev->poll_wait); 687 init_waitqueue_head(&dev->poll_wait);
744 init_waitqueue_head(&dev->read_wait); 688 init_waitqueue_head(&dev->read_wait);
@@ -746,39 +690,37 @@ static dev_link_t *reader_attach(void)
746 init_timer(&dev->poll_timer); 690 init_timer(&dev->poll_timer);
747 dev->poll_timer.function = &cm4040_do_poll; 691 dev->poll_timer.function = &cm4040_do_poll;
748 692
749 return link; 693 link->handle = p_dev;
750} 694 p_dev->instance = link;
751
752static void reader_detach_by_devno(int devno, dev_link_t *link)
753{
754 struct reader_dev *dev = link->priv;
755 695
756 if (link->state & DEV_CONFIG) { 696 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
757 DEBUGP(5, dev, "device still configured (try to release it)\n"); 697 reader_config(link, i);
758 reader_release(link);
759 }
760 698
761 pcmcia_deregister_client(link->handle); 699 return 0;
762 dev_table[devno] = NULL;
763 DEBUGP(5, dev, "freeing dev=%p\n", dev);
764 cm4040_stop_poll(dev);
765 kfree(dev);
766 return;
767} 700}
768 701
769static void reader_detach(dev_link_t *link) 702static void reader_detach(struct pcmcia_device *p_dev)
770{ 703{
771 int i; 704 dev_link_t *link = dev_to_instance(p_dev);
705 struct reader_dev *dev = link->priv;
706 int devno;
772 707
773 /* find device */ 708 /* find device */
774 for (i = 0; i < CM_MAX_DEV; i++) { 709 for (devno = 0; devno < CM_MAX_DEV; devno++) {
775 if (dev_table[i] == link) 710 if (dev_table[devno] == link)
776 break; 711 break;
777 } 712 }
778 if (i == CM_MAX_DEV) 713 if (devno == CM_MAX_DEV)
779 return; 714 return;
780 715
781 reader_detach_by_devno(i, link); 716 link->state &= ~DEV_PRESENT;
717
718 if (link->state & DEV_CONFIG)
719 reader_release(link);
720
721 dev_table[devno] = NULL;
722 kfree(dev);
723
782 return; 724 return;
783} 725}
784 726
@@ -804,9 +746,10 @@ static struct pcmcia_driver reader_driver = {
804 .drv = { 746 .drv = {
805 .name = "cm4040_cs", 747 .name = "cm4040_cs",
806 }, 748 },
807 .attach = reader_attach, 749 .probe = reader_attach,
808 .detach = reader_detach, 750 .remove = reader_detach,
809 .event = reader_event, 751 .suspend = reader_suspend,
752 .resume = reader_resume,
810 .id_table = cm4040_ids, 753 .id_table = cm4040_ids,
811}; 754};
812 755
@@ -825,14 +768,8 @@ static int __init cm4040_init(void)
825 768
826static void __exit cm4040_exit(void) 769static void __exit cm4040_exit(void)
827{ 770{
828 int i;
829
830 printk(KERN_INFO MODULE_NAME ": unloading\n"); 771 printk(KERN_INFO MODULE_NAME ": unloading\n");
831 pcmcia_unregister_driver(&reader_driver); 772 pcmcia_unregister_driver(&reader_driver);
832 for (i = 0; i < CM_MAX_DEV; i++) {
833 if (dev_table[i])
834 reader_detach_by_devno(i, dev_table[i]);
835 }
836 unregister_chrdev(major, DEVICE_NAME); 773 unregister_chrdev(major, DEVICE_NAME);
837} 774}
838 775
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index 2c326ea53421..cf45b100eff1 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -486,13 +486,7 @@ static void mgslpc_wait_until_sent(struct tty_struct *tty, int timeout);
486 486
487static void mgslpc_config(dev_link_t *link); 487static void mgslpc_config(dev_link_t *link);
488static void mgslpc_release(u_long arg); 488static void mgslpc_release(u_long arg);
489static int mgslpc_event(event_t event, int priority, 489static void mgslpc_detach(struct pcmcia_device *p_dev);
490 event_callback_args_t *args);
491static dev_link_t *mgslpc_attach(void);
492static void mgslpc_detach(dev_link_t *);
493
494static dev_info_t dev_info = "synclink_cs";
495static dev_link_t *dev_list = NULL;
496 490
497/* 491/*
498 * 1st function defined in .text section. Calling this function in 492 * 1st function defined in .text section. Calling this function in
@@ -539,12 +533,10 @@ static void ldisc_receive_buf(struct tty_struct *tty,
539 } 533 }
540} 534}
541 535
542static dev_link_t *mgslpc_attach(void) 536static int mgslpc_attach(struct pcmcia_device *p_dev)
543{ 537{
544 MGSLPC_INFO *info; 538 MGSLPC_INFO *info;
545 dev_link_t *link; 539 dev_link_t *link;
546 client_reg_t client_reg;
547 int ret;
548 540
549 if (debug_level >= DEBUG_LEVEL_INFO) 541 if (debug_level >= DEBUG_LEVEL_INFO)
550 printk("mgslpc_attach\n"); 542 printk("mgslpc_attach\n");
@@ -552,7 +544,7 @@ static dev_link_t *mgslpc_attach(void)
552 info = (MGSLPC_INFO *)kmalloc(sizeof(MGSLPC_INFO), GFP_KERNEL); 544 info = (MGSLPC_INFO *)kmalloc(sizeof(MGSLPC_INFO), GFP_KERNEL);
553 if (!info) { 545 if (!info) {
554 printk("Error can't allocate device instance data\n"); 546 printk("Error can't allocate device instance data\n");
555 return NULL; 547 return -ENOMEM;
556 } 548 }
557 549
558 memset(info, 0, sizeof(MGSLPC_INFO)); 550 memset(info, 0, sizeof(MGSLPC_INFO));
@@ -587,24 +579,15 @@ static dev_link_t *mgslpc_attach(void)
587 link->conf.Vcc = 50; 579 link->conf.Vcc = 50;
588 link->conf.IntType = INT_MEMORY_AND_IO; 580 link->conf.IntType = INT_MEMORY_AND_IO;
589 581
590 /* Register with Card Services */ 582 link->handle = p_dev;
591 link->next = dev_list; 583 p_dev->instance = link;
592 dev_list = link;
593
594 client_reg.dev_info = &dev_info;
595 client_reg.Version = 0x0210;
596 client_reg.event_callback_args.client_data = link;
597 584
598 ret = pcmcia_register_client(&link->handle, &client_reg); 585 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
599 if (ret != CS_SUCCESS) { 586 mgslpc_config(link);
600 cs_error(link->handle, RegisterClient, ret);
601 mgslpc_detach(link);
602 return NULL;
603 }
604 587
605 mgslpc_add_device(info); 588 mgslpc_add_device(info);
606 589
607 return link; 590 return 0;
608} 591}
609 592
610/* Card has been inserted. 593/* Card has been inserted.
@@ -736,85 +719,50 @@ static void mgslpc_release(u_long arg)
736 pcmcia_release_io(link->handle, &link->io); 719 pcmcia_release_io(link->handle, &link->io);
737 if (link->irq.AssignedIRQ) 720 if (link->irq.AssignedIRQ)
738 pcmcia_release_irq(link->handle, &link->irq); 721 pcmcia_release_irq(link->handle, &link->irq);
739 if (link->state & DEV_STALE_LINK)
740 mgslpc_detach(link);
741} 722}
742 723
743static void mgslpc_detach(dev_link_t *link) 724static void mgslpc_detach(struct pcmcia_device *p_dev)
744{ 725{
745 dev_link_t **linkp; 726 dev_link_t *link = dev_to_instance(p_dev);
746 727
747 if (debug_level >= DEBUG_LEVEL_INFO) 728 if (debug_level >= DEBUG_LEVEL_INFO)
748 printk("mgslpc_detach(0x%p)\n", link); 729 printk("mgslpc_detach(0x%p)\n", link);
749
750 /* find device */
751 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
752 if (*linkp == link) break;
753 if (*linkp == NULL)
754 return;
755 730
756 if (link->state & DEV_CONFIG) { 731 if (link->state & DEV_CONFIG) {
757 /* device is configured/active, mark it so when 732 ((MGSLPC_INFO *)link->priv)->stop = 1;
758 * release() is called a proper detach() occurs. 733 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 } 734 }
766 735
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 */
772 *linkp = link->next;
773 mgslpc_remove_device((MGSLPC_INFO *)link->priv); 736 mgslpc_remove_device((MGSLPC_INFO *)link->priv);
774} 737}
775 738
776static int mgslpc_event(event_t event, int priority, 739static int mgslpc_suspend(struct pcmcia_device *dev)
777 event_callback_args_t *args)
778{ 740{
779 dev_link_t *link = args->client_data; 741 dev_link_t *link = dev_to_instance(dev);
780 MGSLPC_INFO *info = link->priv; 742 MGSLPC_INFO *info = link->priv;
781 743
782 if (debug_level >= DEBUG_LEVEL_INFO) 744 link->state |= DEV_SUSPEND;
783 printk("mgslpc_event(0x%06x)\n", event); 745 info->stop = 1;
784 746 if (link->state & DEV_CONFIG)
785 switch (event) { 747 pcmcia_release_configuration(link->handle);
786 case CS_EVENT_CARD_REMOVAL: 748
787 link->state &= ~DEV_PRESENT; 749 return 0;
788 if (link->state & DEV_CONFIG) {
789 ((MGSLPC_INFO *)link->priv)->stop = 1;
790 mgslpc_release((u_long)link);
791 }
792 break;
793 case CS_EVENT_CARD_INSERTION:
794 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
795 mgslpc_config(link);
796 break;
797 case CS_EVENT_PM_SUSPEND:
798 link->state |= DEV_SUSPEND;
799 /* Fall through... */
800 case CS_EVENT_RESET_PHYSICAL:
801 /* Mark the device as stopped, to block IO until later */
802 info->stop = 1;
803 if (link->state & DEV_CONFIG)
804 pcmcia_release_configuration(link->handle);
805 break;
806 case CS_EVENT_PM_RESUME:
807 link->state &= ~DEV_SUSPEND;
808 /* Fall through... */
809 case CS_EVENT_CARD_RESET:
810 if (link->state & DEV_CONFIG)
811 pcmcia_request_configuration(link->handle, &link->conf);
812 info->stop = 0;
813 break;
814 }
815 return 0;
816} 750}
817 751
752static int mgslpc_resume(struct pcmcia_device *dev)
753{
754 dev_link_t *link = dev_to_instance(dev);
755 MGSLPC_INFO *info = link->priv;
756
757 link->state &= ~DEV_SUSPEND;
758 if (link->state & DEV_CONFIG)
759 pcmcia_request_configuration(link->handle, &link->conf);
760 info->stop = 0;
761
762 return 0;
763}
764
765
818static inline int mgslpc_paranoia_check(MGSLPC_INFO *info, 766static inline int mgslpc_paranoia_check(MGSLPC_INFO *info,
819 char *name, const char *routine) 767 char *name, const char *routine)
820{ 768{
@@ -3091,10 +3039,11 @@ static struct pcmcia_driver mgslpc_driver = {
3091 .drv = { 3039 .drv = {
3092 .name = "synclink_cs", 3040 .name = "synclink_cs",
3093 }, 3041 },
3094 .attach = mgslpc_attach, 3042 .probe = mgslpc_attach,
3095 .event = mgslpc_event, 3043 .remove = mgslpc_detach,
3096 .detach = mgslpc_detach,
3097 .id_table = mgslpc_ids, 3044 .id_table = mgslpc_ids,
3045 .suspend = mgslpc_suspend,
3046 .resume = mgslpc_resume,
3098}; 3047};
3099 3048
3100static struct tty_operations mgslpc_ops = { 3049static struct tty_operations mgslpc_ops = {
@@ -3138,7 +3087,6 @@ static void synclink_cs_cleanup(void)
3138 } 3087 }
3139 3088
3140 pcmcia_unregister_driver(&mgslpc_driver); 3089 pcmcia_unregister_driver(&mgslpc_driver);
3141 BUG_ON(dev_list != NULL);
3142} 3090}
3143 3091
3144static int __init synclink_cs_init(void) 3092static int __init synclink_cs_init(void)
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
index ef79805218e4..4c2af9020905 100644
--- a/drivers/ide/legacy/ide-cs.c
+++ b/drivers/ide/legacy/ide-cs.c
@@ -88,15 +88,12 @@ typedef struct ide_info_t {
88} ide_info_t; 88} ide_info_t;
89 89
90static void ide_release(dev_link_t *); 90static void ide_release(dev_link_t *);
91static int ide_event(event_t event, int priority, 91static void ide_config(dev_link_t *);
92 event_callback_args_t *args); 92
93static void ide_detach(struct pcmcia_device *p_dev);
93 94
94static dev_info_t dev_info = "ide-cs";
95 95
96static dev_link_t *ide_attach(void);
97static void ide_detach(dev_link_t *);
98 96
99static dev_link_t *dev_list = NULL;
100 97
101/*====================================================================== 98/*======================================================================
102 99
@@ -106,18 +103,17 @@ static dev_link_t *dev_list = NULL;
106 103
107======================================================================*/ 104======================================================================*/
108 105
109static dev_link_t *ide_attach(void) 106static int ide_attach(struct pcmcia_device *p_dev)
110{ 107{
111 ide_info_t *info; 108 ide_info_t *info;
112 dev_link_t *link; 109 dev_link_t *link;
113 client_reg_t client_reg; 110
114 int ret;
115
116 DEBUG(0, "ide_attach()\n"); 111 DEBUG(0, "ide_attach()\n");
117 112
118 /* Create new ide device */ 113 /* Create new ide device */
119 info = kzalloc(sizeof(*info), GFP_KERNEL); 114 info = kzalloc(sizeof(*info), GFP_KERNEL);
120 if (!info) return NULL; 115 if (!info)
116 return -ENOMEM;
121 link = &info->link; link->priv = info; 117 link = &info->link; link->priv = info;
122 118
123 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; 119 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
@@ -128,21 +124,14 @@ static dev_link_t *ide_attach(void)
128 link->conf.Attributes = CONF_ENABLE_IRQ; 124 link->conf.Attributes = CONF_ENABLE_IRQ;
129 link->conf.Vcc = 50; 125 link->conf.Vcc = 50;
130 link->conf.IntType = INT_MEMORY_AND_IO; 126 link->conf.IntType = INT_MEMORY_AND_IO;
131 127
132 /* Register with Card Services */ 128 link->handle = p_dev;
133 link->next = dev_list; 129 p_dev->instance = link;
134 dev_list = link; 130
135 client_reg.dev_info = &dev_info; 131 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
136 client_reg.Version = 0x0210; 132 ide_config(link);
137 client_reg.event_callback_args.client_data = link; 133
138 ret = pcmcia_register_client(&link->handle, &client_reg); 134 return 0;
139 if (ret != CS_SUCCESS) {
140 cs_error(link->handle, RegisterClient, ret);
141 ide_detach(link);
142 return NULL;
143 }
144
145 return link;
146} /* ide_attach */ 135} /* ide_attach */
147 136
148/*====================================================================== 137/*======================================================================
@@ -154,32 +143,16 @@ static dev_link_t *ide_attach(void)
154 143
155======================================================================*/ 144======================================================================*/
156 145
157static void ide_detach(dev_link_t *link) 146static void ide_detach(struct pcmcia_device *p_dev)
158{ 147{
159 dev_link_t **linkp; 148 dev_link_t *link = dev_to_instance(p_dev);
160 int ret;
161 149
162 DEBUG(0, "ide_detach(0x%p)\n", link); 150 DEBUG(0, "ide_detach(0x%p)\n", link);
163
164 /* Locate device structure */
165 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
166 if (*linkp == link) break;
167 if (*linkp == NULL)
168 return;
169 151
170 if (link->state & DEV_CONFIG) 152 if (link->state & DEV_CONFIG)
171 ide_release(link); 153 ide_release(link);
172 154
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 */
180 *linkp = link->next;
181 kfree(link->priv); 155 kfree(link->priv);
182
183} /* ide_detach */ 156} /* ide_detach */
184 157
185static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq, struct pcmcia_device *handle) 158static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq, struct pcmcia_device *handle)
@@ -406,6 +379,28 @@ void ide_release(dev_link_t *link)
406 379
407} /* ide_release */ 380} /* ide_release */
408 381
382static int ide_suspend(struct pcmcia_device *dev)
383{
384 dev_link_t *link = dev_to_instance(dev);
385
386 link->state |= DEV_SUSPEND;
387 if (link->state & DEV_CONFIG)
388 pcmcia_release_configuration(link->handle);
389
390 return 0;
391}
392
393static int ide_resume(struct pcmcia_device *dev)
394{
395 dev_link_t *link = dev_to_instance(dev);
396
397 link->state &= ~DEV_SUSPEND;
398 if (DEV_OK(link))
399 pcmcia_request_configuration(link->handle, &link->conf);
400
401 return 0;
402}
403
409/*====================================================================== 404/*======================================================================
410 405
411 The card status event handler. Mostly, this schedules other 406 The card status event handler. Mostly, this schedules other
@@ -415,48 +410,15 @@ void ide_release(dev_link_t *link)
415 410
416======================================================================*/ 411======================================================================*/
417 412
418int ide_event(event_t event, int priority,
419 event_callback_args_t *args)
420{
421 dev_link_t *link = args->client_data;
422
423 DEBUG(1, "ide_event(0x%06x)\n", event);
424
425 switch (event) {
426 case CS_EVENT_CARD_REMOVAL:
427 link->state &= ~DEV_PRESENT;
428 if (link->state & DEV_CONFIG)
429 ide_release(link);
430 break;
431 case CS_EVENT_CARD_INSERTION:
432 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
433 ide_config(link);
434 break;
435 case CS_EVENT_PM_SUSPEND:
436 link->state |= DEV_SUSPEND;
437 /* Fall through... */
438 case CS_EVENT_RESET_PHYSICAL:
439 if (link->state & DEV_CONFIG)
440 pcmcia_release_configuration(link->handle);
441 break;
442 case CS_EVENT_PM_RESUME:
443 link->state &= ~DEV_SUSPEND;
444 /* Fall through... */
445 case CS_EVENT_CARD_RESET:
446 if (DEV_OK(link))
447 pcmcia_request_configuration(link->handle, &link->conf);
448 break;
449 }
450 return 0;
451} /* ide_event */
452
453static struct pcmcia_device_id ide_ids[] = { 413static struct pcmcia_device_id ide_ids[] = {
454 PCMCIA_DEVICE_FUNC_ID(4), 414 PCMCIA_DEVICE_FUNC_ID(4),
415 PCMCIA_DEVICE_MANF_CARD(0x0007, 0x0000), /* Hitachi */
455 PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704), 416 PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704),
456 PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401), 417 PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401),
457 PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000), /* Toshiba */ 418 PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000), /* Toshiba */
458 PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d), 419 PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d),
459 PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000), /* Samsung */ 420 PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000), /* Samsung */
421 PCMCIA_DEVICE_MANF_CARD(0x0319, 0x0000), /* Hitachi */
460 PCMCIA_DEVICE_MANF_CARD(0x2080, 0x0001), 422 PCMCIA_DEVICE_MANF_CARD(0x2080, 0x0001),
461 PCMCIA_DEVICE_MANF_CARD(0x4e01, 0x0200), /* Lexar */ 423 PCMCIA_DEVICE_MANF_CARD(0x4e01, 0x0200), /* Lexar */
462 PCMCIA_DEVICE_PROD_ID123("Caravelle", "PSC-IDE ", "PSC000", 0x8c36137c, 0xd0693ab8, 0x2768a9f0), 424 PCMCIA_DEVICE_PROD_ID123("Caravelle", "PSC-IDE ", "PSC000", 0x8c36137c, 0xd0693ab8, 0x2768a9f0),
@@ -471,6 +433,8 @@ static struct pcmcia_device_id ide_ids[] = {
471 PCMCIA_DEVICE_PROD_ID12("EXP ", "CD-ROM", 0x0a5c52fd, 0x66536591), 433 PCMCIA_DEVICE_PROD_ID12("EXP ", "CD-ROM", 0x0a5c52fd, 0x66536591),
472 PCMCIA_DEVICE_PROD_ID12("EXP ", "PnPIDE", 0x0a5c52fd, 0x0c694728), 434 PCMCIA_DEVICE_PROD_ID12("EXP ", "PnPIDE", 0x0a5c52fd, 0x0c694728),
473 PCMCIA_DEVICE_PROD_ID12("FREECOM", "PCCARD-IDE", 0x5714cbf7, 0x48e0ab8e), 435 PCMCIA_DEVICE_PROD_ID12("FREECOM", "PCCARD-IDE", 0x5714cbf7, 0x48e0ab8e),
436 PCMCIA_DEVICE_PROD_ID12("HITACHI", "FLASH", 0xf4f43949, 0x9eb86aae),
437 PCMCIA_DEVICE_PROD_ID12("HITACHI", "microdrive", 0xf4f43949, 0xa6d76178),
474 PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753), 438 PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753),
475 PCMCIA_DEVICE_PROD_ID12("IO DATA", "CBIDE2 ", 0x547e66dc, 0x8671043b), 439 PCMCIA_DEVICE_PROD_ID12("IO DATA", "CBIDE2 ", 0x547e66dc, 0x8671043b),
476 PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149), 440 PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149),
@@ -494,10 +458,11 @@ static struct pcmcia_driver ide_cs_driver = {
494 .drv = { 458 .drv = {
495 .name = "ide-cs", 459 .name = "ide-cs",
496 }, 460 },
497 .attach = ide_attach, 461 .probe = ide_attach,
498 .event = ide_event, 462 .remove = ide_detach,
499 .detach = ide_detach,
500 .id_table = ide_ids, 463 .id_table = ide_ids,
464 .suspend = ide_suspend,
465 .resume = ide_resume,
501}; 466};
502 467
503static int __init init_ide_cs(void) 468static int __init init_ide_cs(void)
@@ -508,7 +473,6 @@ static int __init init_ide_cs(void)
508static void __exit exit_ide_cs(void) 473static void __exit exit_ide_cs(void)
509{ 474{
510 pcmcia_unregister_driver(&ide_cs_driver); 475 pcmcia_unregister_driver(&ide_cs_driver);
511 BUG_ON(dev_list != NULL);
512} 476}
513 477
514late_initcall(init_ide_cs); 478late_initcall(init_ide_cs);
diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c
index 27391c32f3eb..2a2b03ff096b 100644
--- a/drivers/isdn/hardware/avm/avm_cs.c
+++ b/drivers/isdn/hardware/avm/avm_cs.c
@@ -53,8 +53,6 @@ MODULE_LICENSE("GPL");
53 53
54static void avmcs_config(dev_link_t *link); 54static void avmcs_config(dev_link_t *link);
55static void avmcs_release(dev_link_t *link); 55static void avmcs_release(dev_link_t *link);
56static int avmcs_event(event_t event, int priority,
57 event_callback_args_t *args);
58 56
59/* 57/*
60 The attach() and detach() entry points are used to create and destroy 58 The attach() and detach() entry points are used to create and destroy
@@ -62,16 +60,7 @@ static int avmcs_event(event_t event, int priority,
62 needed to manage one actual PCMCIA card. 60 needed to manage one actual PCMCIA card.
63*/ 61*/
64 62
65static dev_link_t *avmcs_attach(void); 63static void avmcs_detach(struct pcmcia_device *p_dev);
66static void avmcs_detach(dev_link_t *);
67
68/*
69 The dev_info variable is the "key" that is used to match up this
70 device driver with appropriate cards, through the card configuration
71 database.
72*/
73
74static dev_info_t dev_info = "avm_cs";
75 64
76/* 65/*
77 A linked list of "instances" of the skeleton device. Each actual 66 A linked list of "instances" of the skeleton device. Each actual
@@ -83,15 +72,7 @@ static dev_info_t dev_info = "avm_cs";
83 device numbers are used to derive the corresponding array index. 72 device numbers are used to derive the corresponding array index.
84*/ 73*/
85 74
86static dev_link_t *dev_list = NULL;
87
88/* 75/*
89 A dev_link_t structure has fields for most things that are needed
90 to keep track of a socket, but there will usually be some device
91 specific information that also needs to be kept track of. The
92 'priv' pointer in a dev_link_t structure can be used to point to
93 a device-specific private data structure, like this.
94
95 A driver needs to provide a dev_node_t structure for each device 76 A driver needs to provide a dev_node_t structure for each device
96 on a card. In some cases, there is only one device per card (for 77 on a card. In some cases, there is only one device per card (for
97 example, ethernet cards, modems). In other cases, there may be 78 example, ethernet cards, modems). In other cases, there may be
@@ -118,13 +99,11 @@ typedef struct local_info_t {
118 99
119======================================================================*/ 100======================================================================*/
120 101
121static dev_link_t *avmcs_attach(void) 102static int avmcs_attach(struct pcmcia_device *p_dev)
122{ 103{
123 client_reg_t client_reg;
124 dev_link_t *link; 104 dev_link_t *link;
125 local_info_t *local; 105 local_info_t *local;
126 int ret; 106
127
128 /* Initialize the dev_link_t structure */ 107 /* Initialize the dev_link_t structure */
129 link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); 108 link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
130 if (!link) 109 if (!link)
@@ -155,25 +134,19 @@ static dev_link_t *avmcs_attach(void)
155 goto err_kfree; 134 goto err_kfree;
156 memset(local, 0, sizeof(local_info_t)); 135 memset(local, 0, sizeof(local_info_t));
157 link->priv = local; 136 link->priv = local;
158 137
159 /* Register with Card Services */ 138 link->handle = p_dev;
160 link->next = dev_list; 139 p_dev->instance = link;
161 dev_list = link; 140
162 client_reg.dev_info = &dev_info; 141 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
163 client_reg.Version = 0x0210; 142 avmcs_config(link);
164 client_reg.event_callback_args.client_data = link; 143
165 ret = pcmcia_register_client(&link->handle, &client_reg); 144 return 0;
166 if (ret != 0) {
167 cs_error(link->handle, RegisterClient, ret);
168 avmcs_detach(link);
169 goto err;
170 }
171 return link;
172 145
173 err_kfree: 146 err_kfree:
174 kfree(link); 147 kfree(link);
175 err: 148 err:
176 return NULL; 149 return -EINVAL;
177} /* avmcs_attach */ 150} /* avmcs_attach */
178 151
179/*====================================================================== 152/*======================================================================
@@ -185,33 +158,13 @@ static dev_link_t *avmcs_attach(void)
185 158
186======================================================================*/ 159======================================================================*/
187 160
188static void avmcs_detach(dev_link_t *link) 161static void avmcs_detach(struct pcmcia_device *p_dev)
189{ 162{
190 dev_link_t **linkp; 163 dev_link_t *link = dev_to_instance(p_dev);
191
192 /* Locate device structure */
193 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
194 if (*linkp == link) break;
195 if (*linkp == NULL)
196 return;
197 164
198 /* 165 if (link->state & DEV_CONFIG)
199 If the device is currently configured and active, we won't 166 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 167
209 /* Break the link with Card Services */
210 if (link->handle)
211 pcmcia_deregister_client(link->handle);
212
213 /* Unlink device structure, free pieces */
214 *linkp = link->next;
215 kfree(link->priv); 168 kfree(link->priv);
216 kfree(link); 169 kfree(link);
217} /* avmcs_detach */ 170} /* avmcs_detach */
@@ -424,12 +377,30 @@ static void avmcs_release(dev_link_t *link)
424 pcmcia_release_io(link->handle, &link->io); 377 pcmcia_release_io(link->handle, &link->io);
425 pcmcia_release_irq(link->handle, &link->irq); 378 pcmcia_release_irq(link->handle, &link->irq);
426 link->state &= ~DEV_CONFIG; 379 link->state &= ~DEV_CONFIG;
427
428 if (link->state & DEV_STALE_LINK)
429 avmcs_detach(link);
430
431} /* avmcs_release */ 380} /* avmcs_release */
432 381
382static int avmcs_suspend(struct pcmcia_device *dev)
383{
384 dev_link_t *link = dev_to_instance(dev);
385
386 link->state |= DEV_SUSPEND;
387 if (link->state & DEV_CONFIG)
388 pcmcia_release_configuration(link->handle);
389
390 return 0;
391}
392
393static int avmcs_resume(struct pcmcia_device *dev)
394{
395 dev_link_t *link = dev_to_instance(dev);
396
397 link->state &= ~DEV_SUSPEND;
398 if (link->state & DEV_CONFIG)
399 pcmcia_request_configuration(link->handle, &link->conf);
400
401 return 0;
402}
403
433/*====================================================================== 404/*======================================================================
434 405
435 The card status event handler. Mostly, this schedules other 406 The card status event handler. Mostly, this schedules other
@@ -444,38 +415,6 @@ static void avmcs_release(dev_link_t *link)
444 415
445======================================================================*/ 416======================================================================*/
446 417
447static int avmcs_event(event_t event, int priority,
448 event_callback_args_t *args)
449{
450 dev_link_t *link = args->client_data;
451
452 switch (event) {
453 case CS_EVENT_CARD_REMOVAL:
454 link->state &= ~DEV_PRESENT;
455 if (link->state & DEV_CONFIG)
456 avmcs_release(link);
457 break;
458 case CS_EVENT_CARD_INSERTION:
459 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
460 avmcs_config(link);
461 break;
462 case CS_EVENT_PM_SUSPEND:
463 link->state |= DEV_SUSPEND;
464 /* Fall through... */
465 case CS_EVENT_RESET_PHYSICAL:
466 if (link->state & DEV_CONFIG)
467 pcmcia_release_configuration(link->handle);
468 break;
469 case CS_EVENT_PM_RESUME:
470 link->state &= ~DEV_SUSPEND;
471 /* Fall through... */
472 case CS_EVENT_CARD_RESET:
473 if (link->state & DEV_CONFIG)
474 pcmcia_request_configuration(link->handle, &link->conf);
475 break;
476 }
477 return 0;
478} /* avmcs_event */
479 418
480static struct pcmcia_device_id avmcs_ids[] = { 419static struct pcmcia_device_id avmcs_ids[] = {
481 PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN-Controller B1", 0x95d42008, 0x845dc335), 420 PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN-Controller B1", 0x95d42008, 0x845dc335),
@@ -490,10 +429,11 @@ static struct pcmcia_driver avmcs_driver = {
490 .drv = { 429 .drv = {
491 .name = "avm_cs", 430 .name = "avm_cs",
492 }, 431 },
493 .attach = avmcs_attach, 432 .probe = avmcs_attach,
494 .event = avmcs_event, 433 .remove = avmcs_detach,
495 .detach = avmcs_detach,
496 .id_table = avmcs_ids, 434 .id_table = avmcs_ids,
435 .suspend= avmcs_suspend,
436 .resume = avmcs_resume,
497}; 437};
498 438
499static int __init avmcs_init(void) 439static int __init avmcs_init(void)
@@ -504,7 +444,6 @@ static int __init avmcs_init(void)
504static void __exit avmcs_exit(void) 444static void __exit avmcs_exit(void)
505{ 445{
506 pcmcia_unregister_driver(&avmcs_driver); 446 pcmcia_unregister_driver(&avmcs_driver);
507 BUG_ON(dev_list != NULL);
508} 447}
509 448
510module_init(avmcs_init); 449module_init(avmcs_init);
diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c
index 5f5a5ae740d2..969da40c4248 100644
--- a/drivers/isdn/hisax/avma1_cs.c
+++ b/drivers/isdn/hisax/avma1_cs.c
@@ -69,8 +69,6 @@ module_param(isdnprot, int, 0);
69 69
70static void avma1cs_config(dev_link_t *link); 70static void avma1cs_config(dev_link_t *link);
71static void avma1cs_release(dev_link_t *link); 71static void avma1cs_release(dev_link_t *link);
72static int avma1cs_event(event_t event, int priority,
73 event_callback_args_t *args);
74 72
75/* 73/*
76 The attach() and detach() entry points are used to create and destroy 74 The attach() and detach() entry points are used to create and destroy
@@ -78,16 +76,8 @@ static int avma1cs_event(event_t event, int priority,
78 needed to manage one actual PCMCIA card. 76 needed to manage one actual PCMCIA card.
79*/ 77*/
80 78
81static dev_link_t *avma1cs_attach(void); 79static void avma1cs_detach(struct pcmcia_device *p_dev);
82static void avma1cs_detach(dev_link_t *);
83 80
84/*
85 The dev_info variable is the "key" that is used to match up this
86 device driver with appropriate cards, through the card configuration
87 database.
88*/
89
90static dev_info_t dev_info = "avma1_cs";
91 81
92/* 82/*
93 A linked list of "instances" of the skeleton device. Each actual 83 A linked list of "instances" of the skeleton device. Each actual
@@ -99,15 +89,7 @@ static dev_info_t dev_info = "avma1_cs";
99 device numbers are used to derive the corresponding array index. 89 device numbers are used to derive the corresponding array index.
100*/ 90*/
101 91
102static dev_link_t *dev_list = NULL;
103
104/* 92/*
105 A dev_link_t structure has fields for most things that are needed
106 to keep track of a socket, but there will usually be some device
107 specific information that also needs to be kept track of. The
108 'priv' pointer in a dev_link_t structure can be used to point to
109 a device-specific private data structure, like this.
110
111 A driver needs to provide a dev_node_t structure for each device 93 A driver needs to provide a dev_node_t structure for each device
112 on a card. In some cases, there is only one device per card (for 94 on a card. In some cases, there is only one device per card (for
113 example, ethernet cards, modems). In other cases, there may be 95 example, ethernet cards, modems). In other cases, there may be
@@ -134,26 +116,24 @@ typedef struct local_info_t {
134 116
135======================================================================*/ 117======================================================================*/
136 118
137static dev_link_t *avma1cs_attach(void) 119static int avma1cs_attach(struct pcmcia_device *p_dev)
138{ 120{
139 client_reg_t client_reg;
140 dev_link_t *link; 121 dev_link_t *link;
141 local_info_t *local; 122 local_info_t *local;
142 int ret; 123
143
144 DEBUG(0, "avma1cs_attach()\n"); 124 DEBUG(0, "avma1cs_attach()\n");
145 125
146 /* Initialize the dev_link_t structure */ 126 /* Initialize the dev_link_t structure */
147 link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); 127 link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
148 if (!link) 128 if (!link)
149 return NULL; 129 return -ENOMEM;
150 memset(link, 0, sizeof(struct dev_link_t)); 130 memset(link, 0, sizeof(struct dev_link_t));
151 131
152 /* Allocate space for private device-specific data */ 132 /* Allocate space for private device-specific data */
153 local = kmalloc(sizeof(local_info_t), GFP_KERNEL); 133 local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
154 if (!local) { 134 if (!local) {
155 kfree(link); 135 kfree(link);
156 return NULL; 136 return -ENOMEM;
157 } 137 }
158 memset(local, 0, sizeof(local_info_t)); 138 memset(local, 0, sizeof(local_info_t));
159 link->priv = local; 139 link->priv = local;
@@ -178,20 +158,13 @@ static dev_link_t *avma1cs_attach(void)
178 link->conf.ConfigIndex = 1; 158 link->conf.ConfigIndex = 1;
179 link->conf.Present = PRESENT_OPTION; 159 link->conf.Present = PRESENT_OPTION;
180 160
181 /* Register with Card Services */ 161 link->handle = p_dev;
182 link->next = dev_list; 162 p_dev->instance = link;
183 dev_list = link;
184 client_reg.dev_info = &dev_info;
185 client_reg.Version = 0x0210;
186 client_reg.event_callback_args.client_data = link;
187 ret = pcmcia_register_client(&link->handle, &client_reg);
188 if (ret != 0) {
189 cs_error(link->handle, RegisterClient, ret);
190 avma1cs_detach(link);
191 return NULL;
192 }
193 163
194 return link; 164 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
165 avma1cs_config(link);
166
167 return 0;
195} /* avma1cs_attach */ 168} /* avma1cs_attach */
196 169
197/*====================================================================== 170/*======================================================================
@@ -203,42 +176,17 @@ static dev_link_t *avma1cs_attach(void)
203 176
204======================================================================*/ 177======================================================================*/
205 178
206static void avma1cs_detach(dev_link_t *link) 179static void avma1cs_detach(struct pcmcia_device *p_dev)
207{ 180{
208 dev_link_t **linkp; 181 dev_link_t *link = dev_to_instance(p_dev);
209 182
210 DEBUG(0, "avma1cs_detach(0x%p)\n", link); 183 DEBUG(0, "avma1cs_detach(0x%p)\n", link);
211
212 /* Locate device structure */
213 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
214 if (*linkp == link) break;
215 if (*linkp == NULL)
216 return;
217 184
218 /* 185 if (link->state & DEV_CONFIG)
219 If the device is currently configured and active, we won't 186 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 187
233 /* Break the link with Card Services */
234 if (link->handle)
235 pcmcia_deregister_client(link->handle);
236
237 /* Unlink device structure, free pieces */
238 *linkp = link->next;
239 kfree(link->priv); 188 kfree(link->priv);
240 kfree(link); 189 kfree(link);
241
242} /* avma1cs_detach */ 190} /* avma1cs_detach */
243 191
244/*====================================================================== 192/*======================================================================
@@ -440,58 +388,30 @@ static void avma1cs_release(dev_link_t *link)
440 pcmcia_release_io(link->handle, &link->io); 388 pcmcia_release_io(link->handle, &link->io);
441 pcmcia_release_irq(link->handle, &link->irq); 389 pcmcia_release_irq(link->handle, &link->irq);
442 link->state &= ~DEV_CONFIG; 390 link->state &= ~DEV_CONFIG;
443
444 if (link->state & DEV_STALE_LINK)
445 avma1cs_detach(link);
446} /* avma1cs_release */ 391} /* avma1cs_release */
447 392
448/*====================================================================== 393static int avma1cs_suspend(struct pcmcia_device *dev)
394{
395 dev_link_t *link = dev_to_instance(dev);
449 396
450 The card status event handler. Mostly, this schedules other 397 link->state |= DEV_SUSPEND;
451 stuff to run after an event is received. A CARD_REMOVAL event 398 if (link->state & DEV_CONFIG)
452 also sets some flags to discourage the net drivers from trying 399 pcmcia_release_configuration(link->handle);
453 to talk to the card any more.
454 400
455 When a CARD_REMOVAL event is received, we immediately set a flag 401 return 0;
456 to block future accesses to this device. All the functions that 402}
457 actually access the device should check this flag to make sure
458 the card is still present.
459
460======================================================================*/
461 403
462static int avma1cs_event(event_t event, int priority, 404static int avma1cs_resume(struct pcmcia_device *dev)
463 event_callback_args_t *args)
464{ 405{
465 dev_link_t *link = args->client_data; 406 dev_link_t *link = dev_to_instance(dev);
466 407
467 DEBUG(1, "avma1cs_event(0x%06x)\n", event); 408 link->state &= ~DEV_SUSPEND;
468 409 if (link->state & DEV_CONFIG)
469 switch (event) {
470 case CS_EVENT_CARD_REMOVAL:
471 if (link->state & DEV_CONFIG)
472 avma1cs_release(link);
473 break;
474 case CS_EVENT_CARD_INSERTION:
475 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
476 avma1cs_config(link);
477 break;
478 case CS_EVENT_PM_SUSPEND:
479 link->state |= DEV_SUSPEND;
480 /* Fall through... */
481 case CS_EVENT_RESET_PHYSICAL:
482 if (link->state & DEV_CONFIG)
483 pcmcia_release_configuration(link->handle);
484 break;
485 case CS_EVENT_PM_RESUME:
486 link->state &= ~DEV_SUSPEND;
487 /* Fall through... */
488 case CS_EVENT_CARD_RESET:
489 if (link->state & DEV_CONFIG)
490 pcmcia_request_configuration(link->handle, &link->conf); 410 pcmcia_request_configuration(link->handle, &link->conf);
491 break; 411
492 } 412 return 0;
493 return 0; 413}
494} /* avma1cs_event */ 414
495 415
496static struct pcmcia_device_id avma1cs_ids[] = { 416static struct pcmcia_device_id avma1cs_ids[] = {
497 PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN A", 0x95d42008, 0xadc9d4bb), 417 PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN A", 0x95d42008, 0xadc9d4bb),
@@ -505,10 +425,11 @@ static struct pcmcia_driver avma1cs_driver = {
505 .drv = { 425 .drv = {
506 .name = "avma1_cs", 426 .name = "avma1_cs",
507 }, 427 },
508 .attach = avma1cs_attach, 428 .probe = avma1cs_attach,
509 .event = avma1cs_event, 429 .remove = avma1cs_detach,
510 .detach = avma1cs_detach,
511 .id_table = avma1cs_ids, 430 .id_table = avma1cs_ids,
431 .suspend = avma1cs_suspend,
432 .resume = avma1cs_resume,
512}; 433};
513 434
514/*====================================================================*/ 435/*====================================================================*/
@@ -521,7 +442,6 @@ static int __init init_avma1_cs(void)
521static void __exit exit_avma1_cs(void) 442static void __exit exit_avma1_cs(void)
522{ 443{
523 pcmcia_unregister_driver(&avma1cs_driver); 444 pcmcia_unregister_driver(&avma1cs_driver);
524 BUG_ON(dev_list != NULL);
525} 445}
526 446
527module_init(init_avma1_cs); 447module_init(init_avma1_cs);
diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c
index 6fc6868de0b0..062fb8f0739f 100644
--- a/drivers/isdn/hisax/elsa_cs.c
+++ b/drivers/isdn/hisax/elsa_cs.c
@@ -96,8 +96,6 @@ module_param(protocol, int, 0);
96 96
97static void elsa_cs_config(dev_link_t *link); 97static void elsa_cs_config(dev_link_t *link);
98static void elsa_cs_release(dev_link_t *link); 98static void elsa_cs_release(dev_link_t *link);
99static int elsa_cs_event(event_t event, int priority,
100 event_callback_args_t *args);
101 99
102/* 100/*
103 The attach() and detach() entry points are used to create and destroy 101 The attach() and detach() entry points are used to create and destroy
@@ -105,39 +103,9 @@ static int elsa_cs_event(event_t event, int priority,
105 needed to manage one actual PCMCIA card. 103 needed to manage one actual PCMCIA card.
106*/ 104*/
107 105
108static dev_link_t *elsa_cs_attach(void); 106static void elsa_cs_detach(struct pcmcia_device *p_dev);
109static void elsa_cs_detach(dev_link_t *);
110 107
111/* 108/*
112 The dev_info variable is the "key" that is used to match up this
113 device driver with appropriate cards, through the card configuration
114 database.
115*/
116
117static dev_info_t dev_info = "elsa_cs";
118
119/*
120 A linked list of "instances" of the elsa_cs device. Each actual
121 PCMCIA card corresponds to one device instance, and is described
122 by one dev_link_t structure (defined in ds.h).
123
124 You may not want to use a linked list for this -- for example, the
125 memory card driver uses an array of dev_link_t pointers, where minor
126 device numbers are used to derive the corresponding array index.
127*/
128
129static dev_link_t *dev_list = NULL;
130
131/*
132 A dev_link_t structure has fields for most things that are needed
133 to keep track of a socket, but there will usually be some device
134 specific information that also needs to be kept track of. The
135 'priv' pointer in a dev_link_t structure can be used to point to
136 a device-specific private data structure, like this.
137
138 To simplify the data structure handling, we actually include the
139 dev_link_t structure in the device's private data structure.
140
141 A driver needs to provide a dev_node_t structure for each device 109 A driver needs to provide a dev_node_t structure for each device
142 on a card. In some cases, there is only one device per card (for 110 on a card. In some cases, there is only one device per card (for
143 example, ethernet cards, modems). In other cases, there may be 111 example, ethernet cards, modems). In other cases, there may be
@@ -171,18 +139,16 @@ typedef struct local_info_t {
171 139
172======================================================================*/ 140======================================================================*/
173 141
174static dev_link_t *elsa_cs_attach(void) 142static int elsa_cs_attach(struct pcmcia_device *p_dev)
175{ 143{
176 client_reg_t client_reg;
177 dev_link_t *link; 144 dev_link_t *link;
178 local_info_t *local; 145 local_info_t *local;
179 int ret;
180 146
181 DEBUG(0, "elsa_cs_attach()\n"); 147 DEBUG(0, "elsa_cs_attach()\n");
182 148
183 /* Allocate space for private device-specific data */ 149 /* Allocate space for private device-specific data */
184 local = kmalloc(sizeof(local_info_t), GFP_KERNEL); 150 local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
185 if (!local) return NULL; 151 if (!local) return -ENOMEM;
186 memset(local, 0, sizeof(local_info_t)); 152 memset(local, 0, sizeof(local_info_t));
187 local->cardnr = -1; 153 local->cardnr = -1;
188 link = &local->link; link->priv = local; 154 link = &local->link; link->priv = local;
@@ -207,20 +173,13 @@ static dev_link_t *elsa_cs_attach(void)
207 link->conf.Vcc = 50; 173 link->conf.Vcc = 50;
208 link->conf.IntType = INT_MEMORY_AND_IO; 174 link->conf.IntType = INT_MEMORY_AND_IO;
209 175
210 /* Register with Card Services */ 176 link->handle = p_dev;
211 link->next = dev_list; 177 p_dev->instance = link;
212 dev_list = link;
213 client_reg.dev_info = &dev_info;
214 client_reg.Version = 0x0210;
215 client_reg.event_callback_args.client_data = link;
216 ret = pcmcia_register_client(&link->handle, &client_reg);
217 if (ret != CS_SUCCESS) {
218 cs_error(link->handle, RegisterClient, ret);
219 elsa_cs_detach(link);
220 return NULL;
221 }
222 178
223 return link; 179 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
180 elsa_cs_config(link);
181
182 return 0;
224} /* elsa_cs_attach */ 183} /* elsa_cs_attach */
225 184
226/*====================================================================== 185/*======================================================================
@@ -232,32 +191,18 @@ static dev_link_t *elsa_cs_attach(void)
232 191
233======================================================================*/ 192======================================================================*/
234 193
235static void elsa_cs_detach(dev_link_t *link) 194static void elsa_cs_detach(struct pcmcia_device *p_dev)
236{ 195{
237 dev_link_t **linkp; 196 dev_link_t *link = dev_to_instance(p_dev);
238 local_info_t *info = link->priv; 197 local_info_t *info = link->priv;
239 int ret;
240 198
241 DEBUG(0, "elsa_cs_detach(0x%p)\n", link); 199 DEBUG(0, "elsa_cs_detach(0x%p)\n", link);
242 200
243 /* Locate device structure */ 201 if (link->state & DEV_CONFIG) {
244 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) 202 info->busy = 1;
245 if (*linkp == link) break; 203 elsa_cs_release(link);
246 if (*linkp == NULL)
247 return;
248
249 if (link->state & DEV_CONFIG)
250 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 } 204 }
258 205
259 /* Unlink device structure and free it */
260 *linkp = link->next;
261 kfree(info); 206 kfree(info);
262 207
263} /* elsa_cs_detach */ 208} /* elsa_cs_detach */
@@ -447,60 +392,31 @@ static void elsa_cs_release(dev_link_t *link)
447 link->state &= ~DEV_CONFIG; 392 link->state &= ~DEV_CONFIG;
448} /* elsa_cs_release */ 393} /* elsa_cs_release */
449 394
450/*====================================================================== 395static int elsa_suspend(struct pcmcia_device *p_dev)
451 396{
452 The card status event handler. Mostly, this schedules other 397 dev_link_t *link = dev_to_instance(p_dev);
453 stuff to run after an event is received. A CARD_REMOVAL event 398 local_info_t *dev = link->priv;
454 also sets some flags to discourage the net drivers from trying
455 to talk to the card any more.
456 399
457 When a CARD_REMOVAL event is received, we immediately set a flag 400 link->state |= DEV_SUSPEND;
458 to block future accesses to this device. All the functions that 401 dev->busy = 1;
459 actually access the device should check this flag to make sure 402 if (link->state & DEV_CONFIG)
460 the card is still present. 403 pcmcia_release_configuration(link->handle);
461 404
462======================================================================*/ 405 return 0;
406}
463 407
464static int elsa_cs_event(event_t event, int priority, 408static int elsa_resume(struct pcmcia_device *p_dev)
465 event_callback_args_t *args)
466{ 409{
467 dev_link_t *link = args->client_data; 410 dev_link_t *link = dev_to_instance(p_dev);
468 local_info_t *dev = link->priv; 411 local_info_t *dev = link->priv;
469
470 DEBUG(1, "elsa_cs_event(%d)\n", event);
471 412
472 switch (event) { 413 link->state &= ~DEV_SUSPEND;
473 case CS_EVENT_CARD_REMOVAL: 414 if (link->state & DEV_CONFIG)
474 link->state &= ~DEV_PRESENT; 415 pcmcia_request_configuration(link->handle, &link->conf);
475 if (link->state & DEV_CONFIG) {
476 ((local_info_t*)link->priv)->busy = 1;
477 elsa_cs_release(link);
478 }
479 break;
480 case CS_EVENT_CARD_INSERTION:
481 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
482 elsa_cs_config(link);
483 break;
484 case CS_EVENT_PM_SUSPEND:
485 link->state |= DEV_SUSPEND;
486 /* Fall through... */
487 case CS_EVENT_RESET_PHYSICAL:
488 /* Mark the device as stopped, to block IO until later */
489 dev->busy = 1;
490 if (link->state & DEV_CONFIG)
491 pcmcia_release_configuration(link->handle);
492 break;
493 case CS_EVENT_PM_RESUME:
494 link->state &= ~DEV_SUSPEND;
495 /* Fall through... */
496 case CS_EVENT_CARD_RESET:
497 if (link->state & DEV_CONFIG)
498 pcmcia_request_configuration(link->handle, &link->conf);
499 dev->busy = 0; 416 dev->busy = 0;
500 break; 417
501 } 418 return 0;
502 return 0; 419}
503} /* elsa_cs_event */
504 420
505static struct pcmcia_device_id elsa_ids[] = { 421static struct pcmcia_device_id elsa_ids[] = {
506 PCMCIA_DEVICE_PROD_ID12("ELSA AG (Aachen, Germany)", "MicroLink ISDN/MC ", 0x983de2c4, 0x333ba257), 422 PCMCIA_DEVICE_PROD_ID12("ELSA AG (Aachen, Germany)", "MicroLink ISDN/MC ", 0x983de2c4, 0x333ba257),
@@ -514,10 +430,11 @@ static struct pcmcia_driver elsa_cs_driver = {
514 .drv = { 430 .drv = {
515 .name = "elsa_cs", 431 .name = "elsa_cs",
516 }, 432 },
517 .attach = elsa_cs_attach, 433 .probe = elsa_cs_attach,
518 .event = elsa_cs_event, 434 .remove = elsa_cs_detach,
519 .detach = elsa_cs_detach,
520 .id_table = elsa_ids, 435 .id_table = elsa_ids,
436 .suspend = elsa_suspend,
437 .resume = elsa_resume,
521}; 438};
522 439
523static int __init init_elsa_cs(void) 440static int __init init_elsa_cs(void)
@@ -528,7 +445,6 @@ static int __init init_elsa_cs(void)
528static void __exit exit_elsa_cs(void) 445static void __exit exit_elsa_cs(void)
529{ 446{
530 pcmcia_unregister_driver(&elsa_cs_driver); 447 pcmcia_unregister_driver(&elsa_cs_driver);
531 BUG_ON(dev_list != NULL);
532} 448}
533 449
534module_init(init_elsa_cs); 450module_init(init_elsa_cs);
diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c
index dc334aab433e..6f5213a18a8d 100644
--- a/drivers/isdn/hisax/sedlbauer_cs.c
+++ b/drivers/isdn/hisax/sedlbauer_cs.c
@@ -97,8 +97,6 @@ module_param(protocol, int, 0);
97 97
98static void sedlbauer_config(dev_link_t *link); 98static void sedlbauer_config(dev_link_t *link);
99static void sedlbauer_release(dev_link_t *link); 99static void sedlbauer_release(dev_link_t *link);
100static int sedlbauer_event(event_t event, int priority,
101 event_callback_args_t *args);
102 100
103/* 101/*
104 The attach() and detach() entry points are used to create and destroy 102 The attach() and detach() entry points are used to create and destroy
@@ -106,8 +104,7 @@ static int sedlbauer_event(event_t event, int priority,
106 needed to manage one actual PCMCIA card. 104 needed to manage one actual PCMCIA card.
107*/ 105*/
108 106
109static dev_link_t *sedlbauer_attach(void); 107static void sedlbauer_detach(struct pcmcia_device *p_dev);
110static void sedlbauer_detach(dev_link_t *);
111 108
112/* 109/*
113 You'll also need to prototype all the functions that will actually 110 You'll also need to prototype all the functions that will actually
@@ -117,35 +114,6 @@ static void sedlbauer_detach(dev_link_t *);
117*/ 114*/
118 115
119/* 116/*
120 The dev_info variable is the "key" that is used to match up this
121 device driver with appropriate cards, through the card configuration
122 database.
123*/
124
125static dev_info_t dev_info = "sedlbauer_cs";
126
127/*
128 A linked list of "instances" of the sedlbauer device. Each actual
129 PCMCIA card corresponds to one device instance, and is described
130 by one dev_link_t structure (defined in ds.h).
131
132 You may not want to use a linked list for this -- for example, the
133 memory card driver uses an array of dev_link_t pointers, where minor
134 device numbers are used to derive the corresponding array index.
135*/
136
137static dev_link_t *dev_list = NULL;
138
139/*
140 A dev_link_t structure has fields for most things that are needed
141 to keep track of a socket, but there will usually be some device
142 specific information that also needs to be kept track of. The
143 'priv' pointer in a dev_link_t structure can be used to point to
144 a device-specific private data structure, like this.
145
146 To simplify the data structure handling, we actually include the
147 dev_link_t structure in the device's private data structure.
148
149 A driver needs to provide a dev_node_t structure for each device 117 A driver needs to provide a dev_node_t structure for each device
150 on a card. In some cases, there is only one device per card (for 118 on a card. In some cases, there is only one device per card (for
151 example, ethernet cards, modems). In other cases, there may be 119 example, ethernet cards, modems). In other cases, there may be
@@ -180,18 +148,16 @@ typedef struct local_info_t {
180 148
181======================================================================*/ 149======================================================================*/
182 150
183static dev_link_t *sedlbauer_attach(void) 151static int sedlbauer_attach(struct pcmcia_device *p_dev)
184{ 152{
185 local_info_t *local; 153 local_info_t *local;
186 dev_link_t *link; 154 dev_link_t *link;
187 client_reg_t client_reg;
188 int ret;
189 155
190 DEBUG(0, "sedlbauer_attach()\n"); 156 DEBUG(0, "sedlbauer_attach()\n");
191 157
192 /* Allocate space for private device-specific data */ 158 /* Allocate space for private device-specific data */
193 local = kmalloc(sizeof(local_info_t), GFP_KERNEL); 159 local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
194 if (!local) return NULL; 160 if (!local) return -ENOMEM;
195 memset(local, 0, sizeof(local_info_t)); 161 memset(local, 0, sizeof(local_info_t));
196 local->cardnr = -1; 162 local->cardnr = -1;
197 link = &local->link; link->priv = local; 163 link = &local->link; link->priv = local;
@@ -221,20 +187,13 @@ static dev_link_t *sedlbauer_attach(void)
221 link->conf.Vcc = 50; 187 link->conf.Vcc = 50;
222 link->conf.IntType = INT_MEMORY_AND_IO; 188 link->conf.IntType = INT_MEMORY_AND_IO;
223 189
224 /* Register with Card Services */ 190 link->handle = p_dev;
225 link->next = dev_list; 191 p_dev->instance = link;
226 dev_list = link; 192
227 client_reg.dev_info = &dev_info; 193 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
228 client_reg.Version = 0x0210; 194 sedlbauer_config(link);
229 client_reg.event_callback_args.client_data = link;
230 ret = pcmcia_register_client(&link->handle, &client_reg);
231 if (ret != CS_SUCCESS) {
232 cs_error(link->handle, RegisterClient, ret);
233 sedlbauer_detach(link);
234 return NULL;
235 }
236 195
237 return link; 196 return 0;
238} /* sedlbauer_attach */ 197} /* sedlbauer_attach */
239 198
240/*====================================================================== 199/*======================================================================
@@ -246,39 +205,17 @@ static dev_link_t *sedlbauer_attach(void)
246 205
247======================================================================*/ 206======================================================================*/
248 207
249static void sedlbauer_detach(dev_link_t *link) 208static void sedlbauer_detach(struct pcmcia_device *p_dev)
250{ 209{
251 dev_link_t **linkp; 210 dev_link_t *link = dev_to_instance(p_dev);
252 211
253 DEBUG(0, "sedlbauer_detach(0x%p)\n", link); 212 DEBUG(0, "sedlbauer_detach(0x%p)\n", link);
254
255 /* Locate device structure */
256 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
257 if (*linkp == link) break;
258 if (*linkp == NULL)
259 return;
260 213
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) { 214 if (link->state & DEV_CONFIG) {
268#ifdef PCMCIA_DEBUG 215 ((local_info_t *)link->priv)->stop = 1;
269 printk(KERN_DEBUG "sedlbauer_cs: detach postponed, '%s' " 216 sedlbauer_release(link);
270 "still locked\n", link->dev->dev_name);
271#endif
272 link->state |= DEV_STALE_LINK;
273 return;
274 } 217 }
275 218
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 */
281 *linkp = link->next;
282 /* This points to the parent local_info_t struct */ 219 /* This points to the parent local_info_t struct */
283 kfree(link->priv); 220 kfree(link->priv);
284} /* sedlbauer_detach */ 221} /* sedlbauer_detach */
@@ -547,68 +484,34 @@ static void sedlbauer_release(dev_link_t *link)
547 if (link->irq.AssignedIRQ) 484 if (link->irq.AssignedIRQ)
548 pcmcia_release_irq(link->handle, &link->irq); 485 pcmcia_release_irq(link->handle, &link->irq);
549 link->state &= ~DEV_CONFIG; 486 link->state &= ~DEV_CONFIG;
550
551 if (link->state & DEV_STALE_LINK)
552 sedlbauer_detach(link);
553
554} /* sedlbauer_release */ 487} /* sedlbauer_release */
555 488
556/*====================================================================== 489static int sedlbauer_suspend(struct pcmcia_device *p_dev)
557
558 The card status event handler. Mostly, this schedules other
559 stuff to run after an event is received.
560
561 When a CARD_REMOVAL event is received, we immediately set a
562 private flag to block future accesses to this device. All the
563 functions that actually access the device should check this flag
564 to make sure the card is still present.
565
566======================================================================*/
567
568static int sedlbauer_event(event_t event, int priority,
569 event_callback_args_t *args)
570{ 490{
571 dev_link_t *link = args->client_data; 491 dev_link_t *link = dev_to_instance(p_dev);
572 local_info_t *dev = link->priv; 492 local_info_t *dev = link->priv;
573 493
574 DEBUG(1, "sedlbauer_event(0x%06x)\n", event);
575
576 switch (event) {
577 case CS_EVENT_CARD_REMOVAL:
578 link->state &= ~DEV_PRESENT;
579 if (link->state & DEV_CONFIG) {
580 ((local_info_t *)link->priv)->stop = 1;
581 sedlbauer_release(link);
582 }
583 break;
584 case CS_EVENT_CARD_INSERTION:
585 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
586 sedlbauer_config(link);
587 break;
588 case CS_EVENT_PM_SUSPEND:
589 link->state |= DEV_SUSPEND; 494 link->state |= DEV_SUSPEND;
590 /* Fall through... */
591 case CS_EVENT_RESET_PHYSICAL:
592 /* Mark the device as stopped, to block IO until later */
593 dev->stop = 1; 495 dev->stop = 1;
594 if (link->state & DEV_CONFIG) 496 if (link->state & DEV_CONFIG)
595 pcmcia_release_configuration(link->handle); 497 pcmcia_release_configuration(link->handle);
596 break; 498
597 case CS_EVENT_PM_RESUME: 499 return 0;
500}
501
502static int sedlbauer_resume(struct pcmcia_device *p_dev)
503{
504 dev_link_t *link = dev_to_instance(p_dev);
505 local_info_t *dev = link->priv;
506
598 link->state &= ~DEV_SUSPEND; 507 link->state &= ~DEV_SUSPEND;
599 /* Fall through... */
600 case CS_EVENT_CARD_RESET:
601 if (link->state & DEV_CONFIG) 508 if (link->state & DEV_CONFIG)
602 pcmcia_request_configuration(link->handle, &link->conf); 509 pcmcia_request_configuration(link->handle, &link->conf);
603 dev->stop = 0; 510 dev->stop = 0;
604 /* 511
605 In a normal driver, additional code may go here to restore 512 return 0;
606 the device state and restart IO. 513}
607 */ 514
608 break;
609 }
610 return 0;
611} /* sedlbauer_event */
612 515
613static struct pcmcia_device_id sedlbauer_ids[] = { 516static struct pcmcia_device_id sedlbauer_ids[] = {
614 PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "speed star II", "V 3.1", 0x81fb79f5, 0xf3612e1d, 0x6b95c78a), 517 PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "speed star II", "V 3.1", 0x81fb79f5, 0xf3612e1d, 0x6b95c78a),
@@ -627,10 +530,11 @@ static struct pcmcia_driver sedlbauer_driver = {
627 .drv = { 530 .drv = {
628 .name = "sedlbauer_cs", 531 .name = "sedlbauer_cs",
629 }, 532 },
630 .attach = sedlbauer_attach, 533 .probe = sedlbauer_attach,
631 .event = sedlbauer_event, 534 .remove = sedlbauer_detach,
632 .detach = sedlbauer_detach,
633 .id_table = sedlbauer_ids, 535 .id_table = sedlbauer_ids,
536 .suspend = sedlbauer_suspend,
537 .resume = sedlbauer_resume,
634}; 538};
635 539
636static int __init init_sedlbauer_cs(void) 540static int __init init_sedlbauer_cs(void)
@@ -641,7 +545,6 @@ static int __init init_sedlbauer_cs(void)
641static void __exit exit_sedlbauer_cs(void) 545static void __exit exit_sedlbauer_cs(void)
642{ 546{
643 pcmcia_unregister_driver(&sedlbauer_driver); 547 pcmcia_unregister_driver(&sedlbauer_driver);
644 BUG_ON(dev_list != NULL);
645} 548}
646 549
647module_init(init_sedlbauer_cs); 550module_init(init_sedlbauer_cs);
diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c
index 0ddef1bf778b..4e5c14c7240e 100644
--- a/drivers/isdn/hisax/teles_cs.c
+++ b/drivers/isdn/hisax/teles_cs.c
@@ -77,8 +77,6 @@ module_param(protocol, int, 0);
77 77
78static void teles_cs_config(dev_link_t *link); 78static void teles_cs_config(dev_link_t *link);
79static void teles_cs_release(dev_link_t *link); 79static void teles_cs_release(dev_link_t *link);
80static int teles_cs_event(event_t event, int priority,
81 event_callback_args_t *args);
82 80
83/* 81/*
84 The attach() and detach() entry points are used to create and destroy 82 The attach() and detach() entry points are used to create and destroy
@@ -86,16 +84,7 @@ static int teles_cs_event(event_t event, int priority,
86 needed to manage one actual PCMCIA card. 84 needed to manage one actual PCMCIA card.
87*/ 85*/
88 86
89static dev_link_t *teles_attach(void); 87static void teles_detach(struct pcmcia_device *p_dev);
90static void teles_detach(dev_link_t *);
91
92/*
93 The dev_info variable is the "key" that is used to match up this
94 device driver with appropriate cards, through the card configuration
95 database.
96*/
97
98static dev_info_t dev_info = "teles_cs";
99 88
100/* 89/*
101 A linked list of "instances" of the teles_cs device. Each actual 90 A linked list of "instances" of the teles_cs device. Each actual
@@ -107,18 +96,7 @@ static dev_info_t dev_info = "teles_cs";
107 device numbers are used to derive the corresponding array index. 96 device numbers are used to derive the corresponding array index.
108*/ 97*/
109 98
110static dev_link_t *dev_list = NULL;
111
112/* 99/*
113 A dev_link_t structure has fields for most things that are needed
114 to keep track of a socket, but there will usually be some device
115 specific information that also needs to be kept track of. The
116 'priv' pointer in a dev_link_t structure can be used to point to
117 a device-specific private data structure, like this.
118
119 To simplify the data structure handling, we actually include the
120 dev_link_t structure in the device's private data structure.
121
122 A driver needs to provide a dev_node_t structure for each device 100 A driver needs to provide a dev_node_t structure for each device
123 on a card. In some cases, there is only one device per card (for 101 on a card. In some cases, there is only one device per card (for
124 example, ethernet cards, modems). In other cases, there may be 102 example, ethernet cards, modems). In other cases, there may be
@@ -152,18 +130,16 @@ typedef struct local_info_t {
152 130
153======================================================================*/ 131======================================================================*/
154 132
155static dev_link_t *teles_attach(void) 133static int teles_attach(struct pcmcia_device *p_dev)
156{ 134{
157 client_reg_t client_reg;
158 dev_link_t *link; 135 dev_link_t *link;
159 local_info_t *local; 136 local_info_t *local;
160 int ret;
161 137
162 DEBUG(0, "teles_attach()\n"); 138 DEBUG(0, "teles_attach()\n");
163 139
164 /* Allocate space for private device-specific data */ 140 /* Allocate space for private device-specific data */
165 local = kmalloc(sizeof(local_info_t), GFP_KERNEL); 141 local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
166 if (!local) return NULL; 142 if (!local) return -ENOMEM;
167 memset(local, 0, sizeof(local_info_t)); 143 memset(local, 0, sizeof(local_info_t));
168 local->cardnr = -1; 144 local->cardnr = -1;
169 link = &local->link; link->priv = local; 145 link = &local->link; link->priv = local;
@@ -188,20 +164,13 @@ static dev_link_t *teles_attach(void)
188 link->conf.Vcc = 50; 164 link->conf.Vcc = 50;
189 link->conf.IntType = INT_MEMORY_AND_IO; 165 link->conf.IntType = INT_MEMORY_AND_IO;
190 166
191 /* Register with Card Services */ 167 link->handle = p_dev;
192 link->next = dev_list; 168 p_dev->instance = link;
193 dev_list = link; 169
194 client_reg.dev_info = &dev_info; 170 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
195 client_reg.Version = 0x0210; 171 teles_cs_config(link);
196 client_reg.event_callback_args.client_data = link;
197 ret = pcmcia_register_client(&link->handle, &client_reg);
198 if (ret != CS_SUCCESS) {
199 cs_error(link->handle, RegisterClient, ret);
200 teles_detach(link);
201 return NULL;
202 }
203 172
204 return link; 173 return 0;
205} /* teles_attach */ 174} /* teles_attach */
206 175
207/*====================================================================== 176/*======================================================================
@@ -213,32 +182,18 @@ static dev_link_t *teles_attach(void)
213 182
214======================================================================*/ 183======================================================================*/
215 184
216static void teles_detach(dev_link_t *link) 185static void teles_detach(struct pcmcia_device *p_dev)
217{ 186{
218 dev_link_t **linkp; 187 dev_link_t *link = dev_to_instance(p_dev);
219 local_info_t *info = link->priv; 188 local_info_t *info = link->priv;
220 int ret;
221 189
222 DEBUG(0, "teles_detach(0x%p)\n", link); 190 DEBUG(0, "teles_detach(0x%p)\n", link);
223 191
224 /* Locate device structure */ 192 if (link->state & DEV_CONFIG) {
225 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) 193 info->busy = 1;
226 if (*linkp == link) break; 194 teles_cs_release(link);
227 if (*linkp == NULL)
228 return;
229
230 if (link->state & DEV_CONFIG)
231 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 } 195 }
239 196
240 /* Unlink device structure and free it */
241 *linkp = link->next;
242 kfree(info); 197 kfree(info);
243 198
244} /* teles_detach */ 199} /* teles_detach */
@@ -428,60 +383,32 @@ static void teles_cs_release(dev_link_t *link)
428 link->state &= ~DEV_CONFIG; 383 link->state &= ~DEV_CONFIG;
429} /* teles_cs_release */ 384} /* teles_cs_release */
430 385
431/*====================================================================== 386static int teles_suspend(struct pcmcia_device *p_dev)
432 387{
433 The card status event handler. Mostly, this schedules other 388 dev_link_t *link = dev_to_instance(p_dev);
434 stuff to run after an event is received. A CARD_REMOVAL event 389 local_info_t *dev = link->priv;
435 also sets some flags to discourage the net drivers from trying
436 to talk to the card any more.
437 390
438 When a CARD_REMOVAL event is received, we immediately set a flag 391 link->state |= DEV_SUSPEND;
439 to block future accesses to this device. All the functions that 392 dev->busy = 1;
440 actually access the device should check this flag to make sure 393 if (link->state & DEV_CONFIG)
441 the card is still present. 394 pcmcia_release_configuration(link->handle);
442 395
443======================================================================*/ 396 return 0;
397}
444 398
445static int teles_cs_event(event_t event, int priority, 399static int teles_resume(struct pcmcia_device *p_dev)
446 event_callback_args_t *args)
447{ 400{
448 dev_link_t *link = args->client_data; 401 dev_link_t *link = dev_to_instance(p_dev);
449 local_info_t *dev = link->priv; 402 local_info_t *dev = link->priv;
450
451 DEBUG(1, "teles_cs_event(%d)\n", event);
452 403
453 switch (event) { 404 link->state &= ~DEV_SUSPEND;
454 case CS_EVENT_CARD_REMOVAL: 405 if (link->state & DEV_CONFIG)
455 link->state &= ~DEV_PRESENT; 406 pcmcia_request_configuration(link->handle, &link->conf);
456 if (link->state & DEV_CONFIG) {
457 ((local_info_t*)link->priv)->busy = 1;
458 teles_cs_release(link);
459 }
460 break;
461 case CS_EVENT_CARD_INSERTION:
462 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
463 teles_cs_config(link);
464 break;
465 case CS_EVENT_PM_SUSPEND:
466 link->state |= DEV_SUSPEND;
467 /* Fall through... */
468 case CS_EVENT_RESET_PHYSICAL:
469 /* Mark the device as stopped, to block IO until later */
470 dev->busy = 1;
471 if (link->state & DEV_CONFIG)
472 pcmcia_release_configuration(link->handle);
473 break;
474 case CS_EVENT_PM_RESUME:
475 link->state &= ~DEV_SUSPEND;
476 /* Fall through... */
477 case CS_EVENT_CARD_RESET:
478 if (link->state & DEV_CONFIG)
479 pcmcia_request_configuration(link->handle, &link->conf);
480 dev->busy = 0; 407 dev->busy = 0;
481 break; 408
482 } 409 return 0;
483 return 0; 410}
484} /* teles_cs_event */ 411
485 412
486static struct pcmcia_device_id teles_ids[] = { 413static struct pcmcia_device_id teles_ids[] = {
487 PCMCIA_DEVICE_PROD_ID12("TELES", "S0/PC", 0x67b50eae, 0xe9e70119), 414 PCMCIA_DEVICE_PROD_ID12("TELES", "S0/PC", 0x67b50eae, 0xe9e70119),
@@ -494,10 +421,11 @@ static struct pcmcia_driver teles_cs_driver = {
494 .drv = { 421 .drv = {
495 .name = "teles_cs", 422 .name = "teles_cs",
496 }, 423 },
497 .attach = teles_attach, 424 .probe = teles_attach,
498 .event = teles_cs_event, 425 .remove = teles_detach,
499 .detach = teles_detach,
500 .id_table = teles_ids, 426 .id_table = teles_ids,
427 .suspend = teles_suspend,
428 .resume = teles_resume,
501}; 429};
502 430
503static int __init init_teles_cs(void) 431static int __init init_teles_cs(void)
@@ -508,7 +436,6 @@ static int __init init_teles_cs(void)
508static void __exit exit_teles_cs(void) 436static void __exit exit_teles_cs(void)
509{ 437{
510 pcmcia_unregister_driver(&teles_cs_driver); 438 pcmcia_unregister_driver(&teles_cs_driver);
511 BUG_ON(dev_list != NULL);
512} 439}
513 440
514module_init(init_teles_cs); 441module_init(init_teles_cs);
diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c
index af24216a0626..f0f8916da7ad 100644
--- a/drivers/mtd/maps/pcmciamtd.c
+++ b/drivers/mtd/maps/pcmciamtd.c
@@ -66,9 +66,6 @@ struct pcmciamtd_dev {
66}; 66};
67 67
68 68
69static dev_info_t dev_info = "pcmciamtd";
70static dev_link_t *dev_list;
71
72/* Module parameters */ 69/* Module parameters */
73 70
74/* 2 = do 16-bit transfers, 1 = do 8-bit transfers */ 71/* 2 = do 16-bit transfers, 1 = do 8-bit transfers */
@@ -691,55 +688,21 @@ static void pcmciamtd_config(dev_link_t *link)
691} 688}
692 689
693 690
694/* The card status event handler. Mostly, this schedules other 691static int pcmciamtd_suspend(struct pcmcia_device *dev)
695 * stuff to run after an event is received. A CARD_REMOVAL event 692{
696 * also sets some flags to discourage the driver from trying 693 DEBUG(2, "EVENT_PM_RESUME");
697 * to talk to the card any more. 694
698 */ 695 /* get_lock(link); */
696
697 return 0;
698}
699 699
700static int pcmciamtd_event(event_t event, int priority, 700static int pcmciamtd_resume(struct pcmcia_device *dev)
701 event_callback_args_t *args)
702{ 701{
703 dev_link_t *link = args->client_data; 702 DEBUG(2, "EVENT_PM_SUSPEND");
704 703
705 DEBUG(1, "event=0x%06x", event); 704 /* free_lock(link); */
706 switch (event) { 705
707 case CS_EVENT_CARD_REMOVAL:
708 DEBUG(2, "EVENT_CARD_REMOVAL");
709 link->state &= ~DEV_PRESENT;
710 if (link->state & DEV_CONFIG) {
711 struct pcmciamtd_dev *dev = link->priv;
712 if(dev->mtd_info) {
713 del_mtd_device(dev->mtd_info);
714 info("mtd%d: Removed", dev->mtd_info->index);
715 }
716 pcmciamtd_release(link);
717 }
718 break;
719 case CS_EVENT_CARD_INSERTION:
720 DEBUG(2, "EVENT_CARD_INSERTION");
721 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
722 pcmciamtd_config(link);
723 break;
724 case CS_EVENT_PM_SUSPEND:
725 DEBUG(2, "EVENT_PM_SUSPEND");
726 link->state |= DEV_SUSPEND;
727 /* Fall through... */
728 case CS_EVENT_RESET_PHYSICAL:
729 DEBUG(2, "EVENT_RESET_PHYSICAL");
730 /* get_lock(link); */
731 break;
732 case CS_EVENT_PM_RESUME:
733 DEBUG(2, "EVENT_PM_RESUME");
734 link->state &= ~DEV_SUSPEND;
735 /* Fall through... */
736 case CS_EVENT_CARD_RESET:
737 DEBUG(2, "EVENT_CARD_RESET");
738 /* free_lock(link); */
739 break;
740 default:
741 DEBUG(2, "Unknown event %d", event);
742 }
743 return 0; 706 return 0;
744} 707}
745 708
@@ -750,23 +713,21 @@ static int pcmciamtd_event(event_t event, int priority,
750 * when the device is released. 713 * when the device is released.
751 */ 714 */
752 715
753static void pcmciamtd_detach(dev_link_t *link) 716static void pcmciamtd_detach(struct pcmcia_device *p_dev)
754{ 717{
718 dev_link_t *link = dev_to_instance(p_dev);
719
755 DEBUG(3, "link=0x%p", link); 720 DEBUG(3, "link=0x%p", link);
756 721
757 if(link->state & DEV_CONFIG) { 722 if(link->state & DEV_CONFIG) {
758 pcmciamtd_release(link); 723 struct pcmciamtd_dev *dev = link->priv;
759 } 724 if(dev->mtd_info) {
725 del_mtd_device(dev->mtd_info);
726 info("mtd%d: Removed", dev->mtd_info->index);
727 }
760 728
761 if (link->handle) { 729 pcmciamtd_release(link);
762 int ret;
763 DEBUG(2, "Deregistering with card services");
764 ret = pcmcia_deregister_client(link->handle);
765 if (ret != CS_SUCCESS)
766 cs_error(link->handle, DeregisterClient, ret);
767 } 730 }
768
769 link->state |= DEV_STALE_LINK;
770} 731}
771 732
772 733
@@ -775,16 +736,14 @@ static void pcmciamtd_detach(dev_link_t *link)
775 * with Card Services. 736 * with Card Services.
776 */ 737 */
777 738
778static dev_link_t *pcmciamtd_attach(void) 739static int pcmciamtd_attach(struct pcmcia_device *p_dev)
779{ 740{
780 struct pcmciamtd_dev *dev; 741 struct pcmciamtd_dev *dev;
781 dev_link_t *link; 742 dev_link_t *link;
782 client_reg_t client_reg;
783 int ret;
784 743
785 /* Create new memory card device */ 744 /* Create new memory card device */
786 dev = kmalloc(sizeof(*dev), GFP_KERNEL); 745 dev = kmalloc(sizeof(*dev), GFP_KERNEL);
787 if (!dev) return NULL; 746 if (!dev) return -ENOMEM;
788 DEBUG(1, "dev=0x%p", dev); 747 DEBUG(1, "dev=0x%p", dev);
789 748
790 memset(dev, 0, sizeof(*dev)); 749 memset(dev, 0, sizeof(*dev));
@@ -794,22 +753,14 @@ static dev_link_t *pcmciamtd_attach(void)
794 link->conf.Attributes = 0; 753 link->conf.Attributes = 0;
795 link->conf.IntType = INT_MEMORY; 754 link->conf.IntType = INT_MEMORY;
796 755
797 link->next = dev_list; 756 link->next = NULL;
798 dev_list = link; 757 link->handle = p_dev;
799 758 p_dev->instance = link;
800 /* Register with Card Services */ 759
801 client_reg.dev_info = &dev_info; 760 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
802 client_reg.Version = 0x0210; 761 pcmciamtd_config(link);
803 client_reg.event_callback_args.client_data = link; 762
804 DEBUG(2, "Calling RegisterClient"); 763 return 0;
805 ret = pcmcia_register_client(&link->handle, &client_reg);
806 if (ret != 0) {
807 cs_error(link->handle, RegisterClient, ret);
808 pcmciamtd_detach(link);
809 return NULL;
810 }
811 DEBUG(2, "link = %p", link);
812 return link;
813} 764}
814 765
815static struct pcmcia_device_id pcmciamtd_ids[] = { 766static struct pcmcia_device_id pcmciamtd_ids[] = {
@@ -843,11 +794,12 @@ static struct pcmcia_driver pcmciamtd_driver = {
843 .drv = { 794 .drv = {
844 .name = "pcmciamtd" 795 .name = "pcmciamtd"
845 }, 796 },
846 .attach = pcmciamtd_attach, 797 .probe = pcmciamtd_attach,
847 .event = pcmciamtd_event, 798 .remove = pcmciamtd_detach,
848 .detach = pcmciamtd_detach,
849 .owner = THIS_MODULE, 799 .owner = THIS_MODULE,
850 .id_table = pcmciamtd_ids, 800 .id_table = pcmciamtd_ids,
801 .suspend = pcmciamtd_suspend,
802 .resume = pcmciamtd_resume,
851}; 803};
852 804
853 805
@@ -875,7 +827,6 @@ static void __exit exit_pcmciamtd(void)
875{ 827{
876 DEBUG(1, DRIVER_DESC " unloading"); 828 DEBUG(1, DRIVER_DESC " unloading");
877 pcmcia_unregister_driver(&pcmciamtd_driver); 829 pcmcia_unregister_driver(&pcmciamtd_driver);
878 BUG_ON(dev_list != NULL);
879} 830}
880 831
881module_init(init_pcmciamtd); 832module_init(init_pcmciamtd);
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c
index 71fd41122c91..48774efeec71 100644
--- a/drivers/net/pcmcia/3c574_cs.c
+++ b/drivers/net/pcmcia/3c574_cs.c
@@ -227,8 +227,6 @@ static char mii_preamble_required = 0;
227 227
228static void tc574_config(dev_link_t *link); 228static void tc574_config(dev_link_t *link);
229static void tc574_release(dev_link_t *link); 229static void tc574_release(dev_link_t *link);
230static int tc574_event(event_t event, int priority,
231 event_callback_args_t *args);
232 230
233static void mdio_sync(kio_addr_t ioaddr, int bits); 231static void mdio_sync(kio_addr_t ioaddr, int bits);
234static int mdio_read(kio_addr_t ioaddr, int phy_id, int location); 232static int mdio_read(kio_addr_t ioaddr, int phy_id, int location);
@@ -250,12 +248,7 @@ static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
250static struct ethtool_ops netdev_ethtool_ops; 248static struct ethtool_ops netdev_ethtool_ops;
251static void set_rx_mode(struct net_device *dev); 249static void set_rx_mode(struct net_device *dev);
252 250
253static dev_info_t dev_info = "3c574_cs"; 251static void tc574_detach(struct pcmcia_device *p_dev);
254
255static dev_link_t *tc574_attach(void);
256static void tc574_detach(dev_link_t *);
257
258static dev_link_t *dev_list;
259 252
260/* 253/*
261 tc574_attach() creates an "instance" of the driver, allocating 254 tc574_attach() creates an "instance" of the driver, allocating
@@ -263,20 +256,18 @@ static dev_link_t *dev_list;
263 with Card Services. 256 with Card Services.
264*/ 257*/
265 258
266static dev_link_t *tc574_attach(void) 259static int tc574_attach(struct pcmcia_device *p_dev)
267{ 260{
268 struct el3_private *lp; 261 struct el3_private *lp;
269 client_reg_t client_reg;
270 dev_link_t *link; 262 dev_link_t *link;
271 struct net_device *dev; 263 struct net_device *dev;
272 int ret;
273 264
274 DEBUG(0, "3c574_attach()\n"); 265 DEBUG(0, "3c574_attach()\n");
275 266
276 /* Create the PC card device object. */ 267 /* Create the PC card device object. */
277 dev = alloc_etherdev(sizeof(struct el3_private)); 268 dev = alloc_etherdev(sizeof(struct el3_private));
278 if (!dev) 269 if (!dev)
279 return NULL; 270 return -ENOMEM;
280 lp = netdev_priv(dev); 271 lp = netdev_priv(dev);
281 link = &lp->link; 272 link = &lp->link;
282 link->priv = dev; 273 link->priv = dev;
@@ -307,20 +298,13 @@ static dev_link_t *tc574_attach(void)
307 dev->watchdog_timeo = TX_TIMEOUT; 298 dev->watchdog_timeo = TX_TIMEOUT;
308#endif 299#endif
309 300
310 /* Register with Card Services */ 301 link->handle = p_dev;
311 link->next = dev_list; 302 p_dev->instance = link;
312 dev_list = link;
313 client_reg.dev_info = &dev_info;
314 client_reg.Version = 0x0210;
315 client_reg.event_callback_args.client_data = link;
316 ret = pcmcia_register_client(&link->handle, &client_reg);
317 if (ret != 0) {
318 cs_error(link->handle, RegisterClient, ret);
319 tc574_detach(link);
320 return NULL;
321 }
322 303
323 return link; 304 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
305 tc574_config(link);
306
307 return 0;
324} /* tc574_attach */ 308} /* tc574_attach */
325 309
326/* 310/*
@@ -332,30 +316,19 @@ static dev_link_t *tc574_attach(void)
332 316
333*/ 317*/
334 318
335static void tc574_detach(dev_link_t *link) 319static void tc574_detach(struct pcmcia_device *p_dev)
336{ 320{
321 dev_link_t *link = dev_to_instance(p_dev);
337 struct net_device *dev = link->priv; 322 struct net_device *dev = link->priv;
338 dev_link_t **linkp;
339 323
340 DEBUG(0, "3c574_detach(0x%p)\n", link); 324 DEBUG(0, "3c574_detach(0x%p)\n", link);
341 325
342 /* Locate device structure */
343 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
344 if (*linkp == link) break;
345 if (*linkp == NULL)
346 return;
347
348 if (link->dev) 326 if (link->dev)
349 unregister_netdev(dev); 327 unregister_netdev(dev);
350 328
351 if (link->state & DEV_CONFIG) 329 if (link->state & DEV_CONFIG)
352 tc574_release(link); 330 tc574_release(link);
353 331
354 if (link->handle)
355 pcmcia_deregister_client(link->handle);
356
357 /* Unlink device structure, free bits */
358 *linkp = link->next;
359 free_netdev(dev); 332 free_netdev(dev);
360} /* tc574_detach */ 333} /* tc574_detach */
361 334
@@ -547,56 +520,37 @@ static void tc574_release(dev_link_t *link)
547 link->state &= ~DEV_CONFIG; 520 link->state &= ~DEV_CONFIG;
548} 521}
549 522
550/* 523static int tc574_suspend(struct pcmcia_device *p_dev)
551 The card status event handler. Mostly, this schedules other
552 stuff to run after an event is received. A CARD_REMOVAL event
553 also sets some flags to discourage the net drivers from trying
554 to talk to the card any more.
555*/
556
557static int tc574_event(event_t event, int priority,
558 event_callback_args_t *args)
559{ 524{
560 dev_link_t *link = args->client_data; 525 dev_link_t *link = dev_to_instance(p_dev);
561 struct net_device *dev = link->priv; 526 struct net_device *dev = link->priv;
562 527
563 DEBUG(1, "3c574_event(0x%06x)\n", event); 528 link->state |= DEV_SUSPEND;
564 529 if (link->state & DEV_CONFIG) {
565 switch (event) { 530 if (link->open)
566 case CS_EVENT_CARD_REMOVAL:
567 link->state &= ~DEV_PRESENT;
568 if (link->state & DEV_CONFIG)
569 netif_device_detach(dev); 531 netif_device_detach(dev);
570 break; 532 pcmcia_release_configuration(link->handle);
571 case CS_EVENT_CARD_INSERTION: 533 }
572 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 534
573 tc574_config(link); 535 return 0;
574 break; 536}
575 case CS_EVENT_PM_SUSPEND: 537
576 link->state |= DEV_SUSPEND; 538static int tc574_resume(struct pcmcia_device *p_dev)
577 /* Fall through... */ 539{
578 case CS_EVENT_RESET_PHYSICAL: 540 dev_link_t *link = dev_to_instance(p_dev);
579 if (link->state & DEV_CONFIG) { 541 struct net_device *dev = link->priv;
580 if (link->open) 542
581 netif_device_detach(dev); 543 link->state &= ~DEV_SUSPEND;
582 pcmcia_release_configuration(link->handle); 544 if (link->state & DEV_CONFIG) {
583 } 545 pcmcia_request_configuration(link->handle, &link->conf);
584 break; 546 if (link->open) {
585 case CS_EVENT_PM_RESUME: 547 tc574_reset(dev);
586 link->state &= ~DEV_SUSPEND; 548 netif_device_attach(dev);
587 /* Fall through... */
588 case CS_EVENT_CARD_RESET:
589 if (link->state & DEV_CONFIG) {
590 pcmcia_request_configuration(link->handle, &link->conf);
591 if (link->open) {
592 tc574_reset(dev);
593 netif_device_attach(dev);
594 }
595 } 549 }
596 break;
597 } 550 }
551
598 return 0; 552 return 0;
599} /* tc574_event */ 553}
600 554
601static void dump_status(struct net_device *dev) 555static void dump_status(struct net_device *dev)
602{ 556{
@@ -1292,10 +1246,11 @@ static struct pcmcia_driver tc574_driver = {
1292 .drv = { 1246 .drv = {
1293 .name = "3c574_cs", 1247 .name = "3c574_cs",
1294 }, 1248 },
1295 .attach = tc574_attach, 1249 .probe = tc574_attach,
1296 .event = tc574_event, 1250 .remove = tc574_detach,
1297 .detach = tc574_detach,
1298 .id_table = tc574_ids, 1251 .id_table = tc574_ids,
1252 .suspend = tc574_suspend,
1253 .resume = tc574_resume,
1299}; 1254};
1300 1255
1301static int __init init_tc574(void) 1256static int __init init_tc574(void)
@@ -1306,7 +1261,6 @@ static int __init init_tc574(void)
1306static void __exit exit_tc574(void) 1261static void __exit exit_tc574(void)
1307{ 1262{
1308 pcmcia_unregister_driver(&tc574_driver); 1263 pcmcia_unregister_driver(&tc574_driver);
1309 BUG_ON(dev_list != NULL);
1310} 1264}
1311 1265
1312module_init(init_tc574); 1266module_init(init_tc574);
diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c
index d83fdd8c1943..1c3c9c666f74 100644
--- a/drivers/net/pcmcia/3c589_cs.c
+++ b/drivers/net/pcmcia/3c589_cs.c
@@ -143,8 +143,6 @@ DRV_NAME ".c " DRV_VERSION " 2001/10/13 00:08:50 (David Hinds)";
143 143
144static void tc589_config(dev_link_t *link); 144static void tc589_config(dev_link_t *link);
145static void tc589_release(dev_link_t *link); 145static void tc589_release(dev_link_t *link);
146static int tc589_event(event_t event, int priority,
147 event_callback_args_t *args);
148 146
149static u16 read_eeprom(kio_addr_t ioaddr, int index); 147static u16 read_eeprom(kio_addr_t ioaddr, int index);
150static void tc589_reset(struct net_device *dev); 148static void tc589_reset(struct net_device *dev);
@@ -161,12 +159,7 @@ static void el3_tx_timeout(struct net_device *dev);
161static void set_multicast_list(struct net_device *dev); 159static void set_multicast_list(struct net_device *dev);
162static struct ethtool_ops netdev_ethtool_ops; 160static struct ethtool_ops netdev_ethtool_ops;
163 161
164static dev_info_t dev_info = "3c589_cs"; 162static void tc589_detach(struct pcmcia_device *p_dev);
165
166static dev_link_t *tc589_attach(void);
167static void tc589_detach(dev_link_t *);
168
169static dev_link_t *dev_list;
170 163
171/*====================================================================== 164/*======================================================================
172 165
@@ -176,20 +169,18 @@ static dev_link_t *dev_list;
176 169
177======================================================================*/ 170======================================================================*/
178 171
179static dev_link_t *tc589_attach(void) 172static int tc589_attach(struct pcmcia_device *p_dev)
180{ 173{
181 struct el3_private *lp; 174 struct el3_private *lp;
182 client_reg_t client_reg;
183 dev_link_t *link; 175 dev_link_t *link;
184 struct net_device *dev; 176 struct net_device *dev;
185 int ret;
186 177
187 DEBUG(0, "3c589_attach()\n"); 178 DEBUG(0, "3c589_attach()\n");
188 179
189 /* Create new ethernet device */ 180 /* Create new ethernet device */
190 dev = alloc_etherdev(sizeof(struct el3_private)); 181 dev = alloc_etherdev(sizeof(struct el3_private));
191 if (!dev) 182 if (!dev)
192 return NULL; 183 return -ENOMEM;
193 lp = netdev_priv(dev); 184 lp = netdev_priv(dev);
194 link = &lp->link; 185 link = &lp->link;
195 link->priv = dev; 186 link->priv = dev;
@@ -206,7 +197,7 @@ static dev_link_t *tc589_attach(void)
206 link->conf.IntType = INT_MEMORY_AND_IO; 197 link->conf.IntType = INT_MEMORY_AND_IO;
207 link->conf.ConfigIndex = 1; 198 link->conf.ConfigIndex = 1;
208 link->conf.Present = PRESENT_OPTION; 199 link->conf.Present = PRESENT_OPTION;
209 200
210 /* The EL3-specific entries in the device structure. */ 201 /* The EL3-specific entries in the device structure. */
211 SET_MODULE_OWNER(dev); 202 SET_MODULE_OWNER(dev);
212 dev->hard_start_xmit = &el3_start_xmit; 203 dev->hard_start_xmit = &el3_start_xmit;
@@ -221,20 +212,13 @@ static dev_link_t *tc589_attach(void)
221#endif 212#endif
222 SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); 213 SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
223 214
224 /* Register with Card Services */ 215 link->handle = p_dev;
225 link->next = dev_list; 216 p_dev->instance = link;
226 dev_list = link; 217
227 client_reg.dev_info = &dev_info; 218 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
228 client_reg.Version = 0x0210; 219 tc589_config(link);
229 client_reg.event_callback_args.client_data = link; 220
230 ret = pcmcia_register_client(&link->handle, &client_reg); 221 return 0;
231 if (ret != 0) {
232 cs_error(link->handle, RegisterClient, ret);
233 tc589_detach(link);
234 return NULL;
235 }
236
237 return link;
238} /* tc589_attach */ 222} /* tc589_attach */
239 223
240/*====================================================================== 224/*======================================================================
@@ -246,30 +230,19 @@ static dev_link_t *tc589_attach(void)
246 230
247======================================================================*/ 231======================================================================*/
248 232
249static void tc589_detach(dev_link_t *link) 233static void tc589_detach(struct pcmcia_device *p_dev)
250{ 234{
235 dev_link_t *link = dev_to_instance(p_dev);
251 struct net_device *dev = link->priv; 236 struct net_device *dev = link->priv;
252 dev_link_t **linkp; 237
253
254 DEBUG(0, "3c589_detach(0x%p)\n", link); 238 DEBUG(0, "3c589_detach(0x%p)\n", link);
255
256 /* Locate device structure */
257 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
258 if (*linkp == link) break;
259 if (*linkp == NULL)
260 return;
261 239
262 if (link->dev) 240 if (link->dev)
263 unregister_netdev(dev); 241 unregister_netdev(dev);
264 242
265 if (link->state & DEV_CONFIG) 243 if (link->state & DEV_CONFIG)
266 tc589_release(link); 244 tc589_release(link);
267 245
268 if (link->handle)
269 pcmcia_deregister_client(link->handle);
270
271 /* Unlink device structure, free bits */
272 *linkp = link->next;
273 free_netdev(dev); 246 free_netdev(dev);
274} /* tc589_detach */ 247} /* tc589_detach */
275 248
@@ -421,58 +394,37 @@ static void tc589_release(dev_link_t *link)
421 link->state &= ~DEV_CONFIG; 394 link->state &= ~DEV_CONFIG;
422} 395}
423 396
424/*====================================================================== 397static int tc589_suspend(struct pcmcia_device *p_dev)
425
426 The card status event handler. Mostly, this schedules other
427 stuff to run after an event is received. A CARD_REMOVAL event
428 also sets some flags to discourage the net drivers from trying
429 to talk to the card any more.
430
431======================================================================*/
432
433static int tc589_event(event_t event, int priority,
434 event_callback_args_t *args)
435{ 398{
436 dev_link_t *link = args->client_data; 399 dev_link_t *link = dev_to_instance(p_dev);
437 struct net_device *dev = link->priv; 400 struct net_device *dev = link->priv;
438 401
439 DEBUG(1, "3c589_event(0x%06x)\n", event);
440
441 switch (event) {
442 case CS_EVENT_CARD_REMOVAL:
443 link->state &= ~DEV_PRESENT;
444 if (link->state & DEV_CONFIG)
445 netif_device_detach(dev);
446 break;
447 case CS_EVENT_CARD_INSERTION:
448 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
449 tc589_config(link);
450 break;
451 case CS_EVENT_PM_SUSPEND:
452 link->state |= DEV_SUSPEND; 402 link->state |= DEV_SUSPEND;
453 /* Fall through... */
454 case CS_EVENT_RESET_PHYSICAL:
455 if (link->state & DEV_CONFIG) { 403 if (link->state & DEV_CONFIG) {
456 if (link->open) 404 if (link->open)
457 netif_device_detach(dev); 405 netif_device_detach(dev);
458 pcmcia_release_configuration(link->handle); 406 pcmcia_release_configuration(link->handle);
459 } 407 }
460 break; 408
461 case CS_EVENT_PM_RESUME: 409 return 0;
410}
411
412static int tc589_resume(struct pcmcia_device *p_dev)
413{
414 dev_link_t *link = dev_to_instance(p_dev);
415 struct net_device *dev = link->priv;
416
462 link->state &= ~DEV_SUSPEND; 417 link->state &= ~DEV_SUSPEND;
463 /* Fall through... */
464 case CS_EVENT_CARD_RESET:
465 if (link->state & DEV_CONFIG) { 418 if (link->state & DEV_CONFIG) {
466 pcmcia_request_configuration(link->handle, &link->conf); 419 pcmcia_request_configuration(link->handle, &link->conf);
467 if (link->open) { 420 if (link->open) {
468 tc589_reset(dev); 421 tc589_reset(dev);
469 netif_device_attach(dev); 422 netif_device_attach(dev);
470 } 423 }
471 } 424 }
472 break; 425
473 } 426 return 0;
474 return 0; 427}
475} /* tc589_event */
476 428
477/*====================================================================*/ 429/*====================================================================*/
478 430
@@ -1067,10 +1019,11 @@ static struct pcmcia_driver tc589_driver = {
1067 .drv = { 1019 .drv = {
1068 .name = "3c589_cs", 1020 .name = "3c589_cs",
1069 }, 1021 },
1070 .attach = tc589_attach, 1022 .probe = tc589_attach,
1071 .event = tc589_event, 1023 .remove = tc589_detach,
1072 .detach = tc589_detach,
1073 .id_table = tc589_ids, 1024 .id_table = tc589_ids,
1025 .suspend = tc589_suspend,
1026 .resume = tc589_resume,
1074}; 1027};
1075 1028
1076static int __init init_tc589(void) 1029static int __init init_tc589(void)
@@ -1081,7 +1034,6 @@ static int __init init_tc589(void)
1081static void __exit exit_tc589(void) 1034static void __exit exit_tc589(void)
1082{ 1035{
1083 pcmcia_unregister_driver(&tc589_driver); 1036 pcmcia_unregister_driver(&tc589_driver);
1084 BUG_ON(dev_list != NULL);
1085} 1037}
1086 1038
1087module_init(init_tc589); 1039module_init(init_tc589);
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index 8bb4e85689ea..01ddfc8cce3f 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -87,8 +87,6 @@ static char *version =
87 87
88static void axnet_config(dev_link_t *link); 88static void axnet_config(dev_link_t *link);
89static void axnet_release(dev_link_t *link); 89static void axnet_release(dev_link_t *link);
90static int axnet_event(event_t event, int priority,
91 event_callback_args_t *args);
92static int axnet_open(struct net_device *dev); 90static int axnet_open(struct net_device *dev);
93static int axnet_close(struct net_device *dev); 91static int axnet_close(struct net_device *dev);
94static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); 92static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
@@ -107,11 +105,7 @@ static void block_input(struct net_device *dev, int count,
107static void block_output(struct net_device *dev, int count, 105static void block_output(struct net_device *dev, int count,
108 const u_char *buf, const int start_page); 106 const u_char *buf, const int start_page);
109 107
110static dev_link_t *axnet_attach(void); 108static void axnet_detach(struct pcmcia_device *p_dev);
111static void axnet_detach(dev_link_t *);
112
113static dev_info_t dev_info = "axnet_cs";
114static dev_link_t *dev_list;
115 109
116static void axdev_setup(struct net_device *dev); 110static void axdev_setup(struct net_device *dev);
117static void AX88190_init(struct net_device *dev, int startp); 111static void AX88190_init(struct net_device *dev, int startp);
@@ -147,13 +141,11 @@ static inline axnet_dev_t *PRIV(struct net_device *dev)
147 141
148======================================================================*/ 142======================================================================*/
149 143
150static dev_link_t *axnet_attach(void) 144static int axnet_attach(struct pcmcia_device *p_dev)
151{ 145{
152 axnet_dev_t *info; 146 axnet_dev_t *info;
153 dev_link_t *link; 147 dev_link_t *link;
154 struct net_device *dev; 148 struct net_device *dev;
155 client_reg_t client_reg;
156 int ret;
157 149
158 DEBUG(0, "axnet_attach()\n"); 150 DEBUG(0, "axnet_attach()\n");
159 151
@@ -161,7 +153,7 @@ static dev_link_t *axnet_attach(void)
161 "eth%d", axdev_setup); 153 "eth%d", axdev_setup);
162 154
163 if (!dev) 155 if (!dev)
164 return NULL; 156 return -ENOMEM;
165 157
166 info = PRIV(dev); 158 info = PRIV(dev);
167 link = &info->link; 159 link = &info->link;
@@ -176,20 +168,13 @@ static dev_link_t *axnet_attach(void)
176 dev->do_ioctl = &axnet_ioctl; 168 dev->do_ioctl = &axnet_ioctl;
177 SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); 169 SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
178 170
179 /* Register with Card Services */ 171 link->handle = p_dev;
180 link->next = dev_list; 172 p_dev->instance = link;
181 dev_list = link;
182 client_reg.dev_info = &dev_info;
183 client_reg.Version = 0x0210;
184 client_reg.event_callback_args.client_data = link;
185 ret = pcmcia_register_client(&link->handle, &client_reg);
186 if (ret != CS_SUCCESS) {
187 cs_error(link->handle, RegisterClient, ret);
188 axnet_detach(link);
189 return NULL;
190 }
191 173
192 return link; 174 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
175 axnet_config(link);
176
177 return 0;
193} /* axnet_attach */ 178} /* axnet_attach */
194 179
195/*====================================================================== 180/*======================================================================
@@ -201,30 +186,19 @@ static dev_link_t *axnet_attach(void)
201 186
202======================================================================*/ 187======================================================================*/
203 188
204static void axnet_detach(dev_link_t *link) 189static void axnet_detach(struct pcmcia_device *p_dev)
205{ 190{
191 dev_link_t *link = dev_to_instance(p_dev);
206 struct net_device *dev = link->priv; 192 struct net_device *dev = link->priv;
207 dev_link_t **linkp;
208 193
209 DEBUG(0, "axnet_detach(0x%p)\n", link); 194 DEBUG(0, "axnet_detach(0x%p)\n", link);
210 195
211 /* Locate device structure */
212 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
213 if (*linkp == link) break;
214 if (*linkp == NULL)
215 return;
216
217 if (link->dev) 196 if (link->dev)
218 unregister_netdev(dev); 197 unregister_netdev(dev);
219 198
220 if (link->state & DEV_CONFIG) 199 if (link->state & DEV_CONFIG)
221 axnet_release(link); 200 axnet_release(link);
222 201
223 if (link->handle)
224 pcmcia_deregister_client(link->handle);
225
226 /* Unlink device structure, free bits */
227 *linkp = link->next;
228 free_netdev(dev); 202 free_netdev(dev);
229} /* axnet_detach */ 203} /* axnet_detach */
230 204
@@ -490,59 +464,39 @@ static void axnet_release(dev_link_t *link)
490 link->state &= ~DEV_CONFIG; 464 link->state &= ~DEV_CONFIG;
491} 465}
492 466
493/*====================================================================== 467static int axnet_suspend(struct pcmcia_device *p_dev)
494
495 The card status event handler. Mostly, this schedules other
496 stuff to run after an event is received. A CARD_REMOVAL event
497 also sets some flags to discourage the net drivers from trying
498 to talk to the card any more.
499
500======================================================================*/
501
502static int axnet_event(event_t event, int priority,
503 event_callback_args_t *args)
504{ 468{
505 dev_link_t *link = args->client_data; 469 dev_link_t *link = dev_to_instance(p_dev);
506 struct net_device *dev = link->priv; 470 struct net_device *dev = link->priv;
507 471
508 DEBUG(2, "axnet_event(0x%06x)\n", event);
509
510 switch (event) {
511 case CS_EVENT_CARD_REMOVAL:
512 link->state &= ~DEV_PRESENT;
513 if (link->state & DEV_CONFIG)
514 netif_device_detach(dev);
515 break;
516 case CS_EVENT_CARD_INSERTION:
517 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
518 axnet_config(link);
519 break;
520 case CS_EVENT_PM_SUSPEND:
521 link->state |= DEV_SUSPEND; 472 link->state |= DEV_SUSPEND;
522 /* Fall through... */
523 case CS_EVENT_RESET_PHYSICAL:
524 if (link->state & DEV_CONFIG) { 473 if (link->state & DEV_CONFIG) {
525 if (link->open) 474 if (link->open)
526 netif_device_detach(dev); 475 netif_device_detach(dev);
527 pcmcia_release_configuration(link->handle); 476 pcmcia_release_configuration(link->handle);
528 } 477 }
529 break; 478
530 case CS_EVENT_PM_RESUME: 479 return 0;
480}
481
482static int axnet_resume(struct pcmcia_device *p_dev)
483{
484 dev_link_t *link = dev_to_instance(p_dev);
485 struct net_device *dev = link->priv;
486
531 link->state &= ~DEV_SUSPEND; 487 link->state &= ~DEV_SUSPEND;
532 /* Fall through... */
533 case CS_EVENT_CARD_RESET:
534 if (link->state & DEV_CONFIG) { 488 if (link->state & DEV_CONFIG) {
535 pcmcia_request_configuration(link->handle, &link->conf); 489 pcmcia_request_configuration(link->handle, &link->conf);
536 if (link->open) { 490 if (link->open) {
537 axnet_reset_8390(dev); 491 axnet_reset_8390(dev);
538 AX88190_init(dev, 1); 492 AX88190_init(dev, 1);
539 netif_device_attach(dev); 493 netif_device_attach(dev);
540 } 494 }
541 } 495 }
542 break; 496
543 } 497 return 0;
544 return 0; 498}
545} /* axnet_event */ 499
546 500
547/*====================================================================== 501/*======================================================================
548 502
@@ -616,7 +570,7 @@ static int axnet_open(struct net_device *dev)
616 570
617 link->open++; 571 link->open++;
618 572
619 request_irq(dev->irq, ei_irq_wrapper, SA_SHIRQ, dev_info, dev); 573 request_irq(dev->irq, ei_irq_wrapper, SA_SHIRQ, "axnet_cs", dev);
620 574
621 info->link_status = 0x00; 575 info->link_status = 0x00;
622 init_timer(&info->watchdog); 576 init_timer(&info->watchdog);
@@ -877,10 +831,11 @@ static struct pcmcia_driver axnet_cs_driver = {
877 .drv = { 831 .drv = {
878 .name = "axnet_cs", 832 .name = "axnet_cs",
879 }, 833 },
880 .attach = axnet_attach, 834 .probe = axnet_attach,
881 .event = axnet_event, 835 .remove = axnet_detach,
882 .detach = axnet_detach,
883 .id_table = axnet_ids, 836 .id_table = axnet_ids,
837 .suspend = axnet_suspend,
838 .resume = axnet_resume,
884}; 839};
885 840
886static int __init init_axnet_cs(void) 841static int __init init_axnet_cs(void)
@@ -891,7 +846,6 @@ static int __init init_axnet_cs(void)
891static void __exit exit_axnet_cs(void) 846static void __exit exit_axnet_cs(void)
892{ 847{
893 pcmcia_unregister_driver(&axnet_cs_driver); 848 pcmcia_unregister_driver(&axnet_cs_driver);
894 BUG_ON(dev_list != NULL);
895} 849}
896 850
897module_init(init_axnet_cs); 851module_init(init_axnet_cs);
diff --git a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c
index b9355d9498a3..2827a48ea37c 100644
--- a/drivers/net/pcmcia/com20020_cs.c
+++ b/drivers/net/pcmcia/com20020_cs.c
@@ -120,15 +120,8 @@ MODULE_LICENSE("GPL");
120 120
121static void com20020_config(dev_link_t *link); 121static void com20020_config(dev_link_t *link);
122static void com20020_release(dev_link_t *link); 122static void com20020_release(dev_link_t *link);
123static int com20020_event(event_t event, int priority,
124 event_callback_args_t *args);
125 123
126static dev_info_t dev_info = "com20020_cs"; 124static void com20020_detach(struct pcmcia_device *p_dev);
127
128static dev_link_t *com20020_attach(void);
129static void com20020_detach(dev_link_t *);
130
131static dev_link_t *dev_list;
132 125
133/*====================================================================*/ 126/*====================================================================*/
134 127
@@ -145,21 +138,19 @@ typedef struct com20020_dev_t {
145 138
146======================================================================*/ 139======================================================================*/
147 140
148static dev_link_t *com20020_attach(void) 141static int com20020_attach(struct pcmcia_device *p_dev)
149{ 142{
150 client_reg_t client_reg;
151 dev_link_t *link; 143 dev_link_t *link;
152 com20020_dev_t *info; 144 com20020_dev_t *info;
153 struct net_device *dev; 145 struct net_device *dev;
154 int ret;
155 struct arcnet_local *lp; 146 struct arcnet_local *lp;
156 147
157 DEBUG(0, "com20020_attach()\n"); 148 DEBUG(0, "com20020_attach()\n");
158 149
159 /* Create new network device */ 150 /* Create new network device */
160 link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); 151 link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
161 if (!link) 152 if (!link)
162 return NULL; 153 return -ENOMEM;
163 154
164 info = kmalloc(sizeof(struct com20020_dev_t), GFP_KERNEL); 155 info = kmalloc(sizeof(struct com20020_dev_t), GFP_KERNEL);
165 if (!info) 156 if (!info)
@@ -191,30 +182,19 @@ static dev_link_t *com20020_attach(void)
191 link->conf.IntType = INT_MEMORY_AND_IO; 182 link->conf.IntType = INT_MEMORY_AND_IO;
192 link->conf.Present = PRESENT_OPTION; 183 link->conf.Present = PRESENT_OPTION;
193 184
194
195 link->irq.Instance = info->dev = dev; 185 link->irq.Instance = info->dev = dev;
196 link->priv = info; 186 link->priv = info;
197 187
198 /* Register with Card Services */ 188 link->state |= DEV_PRESENT;
199 link->next = dev_list; 189 com20020_config(link);
200 dev_list = link;
201 client_reg.dev_info = &dev_info;
202 client_reg.Version = 0x0210;
203 client_reg.event_callback_args.client_data = link;
204 ret = pcmcia_register_client(&link->handle, &client_reg);
205 if (ret != 0) {
206 cs_error(link->handle, RegisterClient, ret);
207 com20020_detach(link);
208 return NULL;
209 }
210 190
211 return link; 191 return 0;
212 192
213fail_alloc_dev: 193fail_alloc_dev:
214 kfree(info); 194 kfree(info);
215fail_alloc_info: 195fail_alloc_info:
216 kfree(link); 196 kfree(link);
217 return NULL; 197 return -ENOMEM;
218} /* com20020_attach */ 198} /* com20020_attach */
219 199
220/*====================================================================== 200/*======================================================================
@@ -226,29 +206,21 @@ fail_alloc_info:
226 206
227======================================================================*/ 207======================================================================*/
228 208
229static void com20020_detach(dev_link_t *link) 209static void com20020_detach(struct pcmcia_device *p_dev)
230{ 210{
211 dev_link_t *link = dev_to_instance(p_dev);
231 struct com20020_dev_t *info = link->priv; 212 struct com20020_dev_t *info = link->priv;
232 dev_link_t **linkp; 213 struct net_device *dev = info->dev;
233 struct net_device *dev; 214
234
235 DEBUG(1,"detach...\n"); 215 DEBUG(1,"detach...\n");
236 216
237 DEBUG(0, "com20020_detach(0x%p)\n", link); 217 DEBUG(0, "com20020_detach(0x%p)\n", link);
238 218
239 /* Locate device structure */
240 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
241 if (*linkp == link) break;
242 if (*linkp == NULL)
243 return;
244
245 dev = info->dev;
246
247 if (link->dev) { 219 if (link->dev) {
248 DEBUG(1,"unregister...\n"); 220 DEBUG(1,"unregister...\n");
249 221
250 unregister_netdev(dev); 222 unregister_netdev(dev);
251 223
252 /* 224 /*
253 * this is necessary because we register our IRQ separately 225 * this is necessary because we register our IRQ separately
254 * from card services. 226 * from card services.
@@ -260,12 +232,8 @@ static void com20020_detach(dev_link_t *link)
260 if (link->state & DEV_CONFIG) 232 if (link->state & DEV_CONFIG)
261 com20020_release(link); 233 com20020_release(link);
262 234
263 if (link->handle)
264 pcmcia_deregister_client(link->handle);
265
266 /* Unlink device structure, free bits */ 235 /* Unlink device structure, free bits */
267 DEBUG(1,"unlinking...\n"); 236 DEBUG(1,"unlinking...\n");
268 *linkp = link->next;
269 if (link->priv) 237 if (link->priv)
270 { 238 {
271 dev = info->dev; 239 dev = info->dev;
@@ -421,61 +389,41 @@ static void com20020_release(dev_link_t *link)
421 link->state &= ~(DEV_CONFIG | DEV_RELEASE_PENDING); 389 link->state &= ~(DEV_CONFIG | DEV_RELEASE_PENDING);
422} 390}
423 391
424/*====================================================================== 392static int com20020_suspend(struct pcmcia_device *p_dev)
393{
394 dev_link_t *link = dev_to_instance(p_dev);
395 com20020_dev_t *info = link->priv;
396 struct net_device *dev = info->dev;
425 397
426 The card status event handler. Mostly, this schedules other 398 link->state |= DEV_SUSPEND;
427 stuff to run after an event is received. A CARD_REMOVAL event 399 if (link->state & DEV_CONFIG) {
428 also sets some flags to discourage the net drivers from trying 400 if (link->open) {
429 to talk to the card any more. 401 netif_device_detach(dev);
402 }
403 pcmcia_release_configuration(link->handle);
404 }
430 405
431======================================================================*/ 406 return 0;
407}
432 408
433static int com20020_event(event_t event, int priority, 409static int com20020_resume(struct pcmcia_device *p_dev)
434 event_callback_args_t *args)
435{ 410{
436 dev_link_t *link = args->client_data; 411 dev_link_t *link = dev_to_instance(p_dev);
437 com20020_dev_t *info = link->priv; 412 com20020_dev_t *info = link->priv;
438 struct net_device *dev = info->dev; 413 struct net_device *dev = info->dev;
439 414
440 DEBUG(1, "com20020_event(0x%06x)\n", event); 415 link->state &= ~DEV_SUSPEND;
441
442 switch (event) {
443 case CS_EVENT_CARD_REMOVAL:
444 link->state &= ~DEV_PRESENT;
445 if (link->state & DEV_CONFIG)
446 netif_device_detach(dev);
447 break;
448 case CS_EVENT_CARD_INSERTION:
449 link->state |= DEV_PRESENT;
450 com20020_config(link);
451 break;
452 case CS_EVENT_PM_SUSPEND:
453 link->state |= DEV_SUSPEND;
454 /* Fall through... */
455 case CS_EVENT_RESET_PHYSICAL:
456 if (link->state & DEV_CONFIG) {
457 if (link->open) {
458 netif_device_detach(dev);
459 }
460 pcmcia_release_configuration(link->handle);
461 }
462 break;
463 case CS_EVENT_PM_RESUME:
464 link->state &= ~DEV_SUSPEND;
465 /* Fall through... */
466 case CS_EVENT_CARD_RESET:
467 if (link->state & DEV_CONFIG) { 416 if (link->state & DEV_CONFIG) {
468 pcmcia_request_configuration(link->handle, &link->conf); 417 pcmcia_request_configuration(link->handle, &link->conf);
469 if (link->open) { 418 if (link->open) {
470 int ioaddr = dev->base_addr; 419 int ioaddr = dev->base_addr;
471 struct arcnet_local *lp = dev->priv; 420 struct arcnet_local *lp = dev->priv;
472 ARCRESET; 421 ARCRESET;
473 } 422 }
474 } 423 }
475 break; 424
476 } 425 return 0;
477 return 0; 426}
478} /* com20020_event */
479 427
480static struct pcmcia_device_id com20020_ids[] = { 428static struct pcmcia_device_id com20020_ids[] = {
481 PCMCIA_DEVICE_PROD_ID12("Contemporary Control Systems, Inc.", "PCM20 Arcnet Adapter", 0x59991666, 0x95dfffaf), 429 PCMCIA_DEVICE_PROD_ID12("Contemporary Control Systems, Inc.", "PCM20 Arcnet Adapter", 0x59991666, 0x95dfffaf),
@@ -488,10 +436,11 @@ static struct pcmcia_driver com20020_cs_driver = {
488 .drv = { 436 .drv = {
489 .name = "com20020_cs", 437 .name = "com20020_cs",
490 }, 438 },
491 .attach = com20020_attach, 439 .probe = com20020_attach,
492 .event = com20020_event, 440 .remove = com20020_detach,
493 .detach = com20020_detach,
494 .id_table = com20020_ids, 441 .id_table = com20020_ids,
442 .suspend = com20020_suspend,
443 .resume = com20020_resume,
495}; 444};
496 445
497static int __init init_com20020_cs(void) 446static int __init init_com20020_cs(void)
@@ -502,7 +451,6 @@ static int __init init_com20020_cs(void)
502static void __exit exit_com20020_cs(void) 451static void __exit exit_com20020_cs(void)
503{ 452{
504 pcmcia_unregister_driver(&com20020_cs_driver); 453 pcmcia_unregister_driver(&com20020_cs_driver);
505 BUG_ON(dev_list != NULL);
506} 454}
507 455
508module_init(init_com20020_cs); 456module_init(init_com20020_cs);
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c
index 356f50909222..28fe2fb4d6c0 100644
--- a/drivers/net/pcmcia/fmvj18x_cs.c
+++ b/drivers/net/pcmcia/fmvj18x_cs.c
@@ -88,10 +88,7 @@ static void fmvj18x_config(dev_link_t *link);
88static int fmvj18x_get_hwinfo(dev_link_t *link, u_char *node_id); 88static int fmvj18x_get_hwinfo(dev_link_t *link, u_char *node_id);
89static int fmvj18x_setup_mfc(dev_link_t *link); 89static int fmvj18x_setup_mfc(dev_link_t *link);
90static void fmvj18x_release(dev_link_t *link); 90static void fmvj18x_release(dev_link_t *link);
91static int fmvj18x_event(event_t event, int priority, 91static void fmvj18x_detach(struct pcmcia_device *p_dev);
92 event_callback_args_t *args);
93static dev_link_t *fmvj18x_attach(void);
94static void fmvj18x_detach(dev_link_t *);
95 92
96/* 93/*
97 LAN controller(MBH86960A) specific routines 94 LAN controller(MBH86960A) specific routines
@@ -108,9 +105,6 @@ static void set_rx_mode(struct net_device *dev);
108static void fjn_tx_timeout(struct net_device *dev); 105static void fjn_tx_timeout(struct net_device *dev);
109static struct ethtool_ops netdev_ethtool_ops; 106static struct ethtool_ops netdev_ethtool_ops;
110 107
111static dev_info_t dev_info = "fmvj18x_cs";
112static dev_link_t *dev_list;
113
114/* 108/*
115 card type 109 card type
116 */ 110 */
@@ -234,20 +228,18 @@ typedef struct local_info_t {
234#define BANK_1U 0x24 /* bank 1 (CONFIG_1) */ 228#define BANK_1U 0x24 /* bank 1 (CONFIG_1) */
235#define BANK_2U 0x28 /* bank 2 (CONFIG_1) */ 229#define BANK_2U 0x28 /* bank 2 (CONFIG_1) */
236 230
237static dev_link_t *fmvj18x_attach(void) 231static int fmvj18x_attach(struct pcmcia_device *p_dev)
238{ 232{
239 local_info_t *lp; 233 local_info_t *lp;
240 dev_link_t *link; 234 dev_link_t *link;
241 struct net_device *dev; 235 struct net_device *dev;
242 client_reg_t client_reg; 236
243 int ret;
244
245 DEBUG(0, "fmvj18x_attach()\n"); 237 DEBUG(0, "fmvj18x_attach()\n");
246 238
247 /* Make up a FMVJ18x specific data structure */ 239 /* Make up a FMVJ18x specific data structure */
248 dev = alloc_etherdev(sizeof(local_info_t)); 240 dev = alloc_etherdev(sizeof(local_info_t));
249 if (!dev) 241 if (!dev)
250 return NULL; 242 return -ENOMEM;
251 lp = netdev_priv(dev); 243 lp = netdev_priv(dev);
252 link = &lp->link; 244 link = &lp->link;
253 link->priv = dev; 245 link->priv = dev;
@@ -262,7 +254,7 @@ static dev_link_t *fmvj18x_attach(void)
262 link->irq.IRQInfo1 = IRQ_LEVEL_ID; 254 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
263 link->irq.Handler = &fjn_interrupt; 255 link->irq.Handler = &fjn_interrupt;
264 link->irq.Instance = dev; 256 link->irq.Instance = dev;
265 257
266 /* General socket configuration */ 258 /* General socket configuration */
267 link->conf.Attributes = CONF_ENABLE_IRQ; 259 link->conf.Attributes = CONF_ENABLE_IRQ;
268 link->conf.Vcc = 50; 260 link->conf.Vcc = 50;
@@ -281,37 +273,24 @@ static dev_link_t *fmvj18x_attach(void)
281 dev->watchdog_timeo = TX_TIMEOUT; 273 dev->watchdog_timeo = TX_TIMEOUT;
282#endif 274#endif
283 SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); 275 SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
284
285 /* Register with Card Services */
286 link->next = dev_list;
287 dev_list = link;
288 client_reg.dev_info = &dev_info;
289 client_reg.Version = 0x0210;
290 client_reg.event_callback_args.client_data = link;
291 ret = pcmcia_register_client(&link->handle, &client_reg);
292 if (ret != 0) {
293 cs_error(link->handle, RegisterClient, ret);
294 fmvj18x_detach(link);
295 return NULL;
296 }
297 276
298 return link; 277 link->handle = p_dev;
278 p_dev->instance = link;
279
280 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
281 fmvj18x_config(link);
282
283 return 0;
299} /* fmvj18x_attach */ 284} /* fmvj18x_attach */
300 285
301/*====================================================================*/ 286/*====================================================================*/
302 287
303static void fmvj18x_detach(dev_link_t *link) 288static void fmvj18x_detach(struct pcmcia_device *p_dev)
304{ 289{
290 dev_link_t *link = dev_to_instance(p_dev);
305 struct net_device *dev = link->priv; 291 struct net_device *dev = link->priv;
306 dev_link_t **linkp; 292
307
308 DEBUG(0, "fmvj18x_detach(0x%p)\n", link); 293 DEBUG(0, "fmvj18x_detach(0x%p)\n", link);
309
310 /* Locate device structure */
311 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
312 if (*linkp == link) break;
313 if (*linkp == NULL)
314 return;
315 294
316 if (link->dev) 295 if (link->dev)
317 unregister_netdev(dev); 296 unregister_netdev(dev);
@@ -319,12 +298,6 @@ static void fmvj18x_detach(dev_link_t *link)
319 if (link->state & DEV_CONFIG) 298 if (link->state & DEV_CONFIG)
320 fmvj18x_release(link); 299 fmvj18x_release(link);
321 300
322 /* Break the link with Card Services */
323 if (link->handle)
324 pcmcia_deregister_client(link->handle);
325
326 /* Unlink device structure, free pieces */
327 *linkp = link->next;
328 free_netdev(dev); 301 free_netdev(dev);
329} /* fmvj18x_detach */ 302} /* fmvj18x_detach */
330 303
@@ -713,51 +686,40 @@ static void fmvj18x_release(dev_link_t *link)
713 link->state &= ~DEV_CONFIG; 686 link->state &= ~DEV_CONFIG;
714} 687}
715 688
716/*====================================================================*/ 689static int fmvj18x_suspend(struct pcmcia_device *p_dev)
717
718static int fmvj18x_event(event_t event, int priority,
719 event_callback_args_t *args)
720{ 690{
721 dev_link_t *link = args->client_data; 691 dev_link_t *link = dev_to_instance(p_dev);
722 struct net_device *dev = link->priv; 692 struct net_device *dev = link->priv;
723 693
724 DEBUG(1, "fmvj18x_event(0x%06x)\n", event);
725
726 switch (event) {
727 case CS_EVENT_CARD_REMOVAL:
728 link->state &= ~DEV_PRESENT;
729 if (link->state & DEV_CONFIG)
730 netif_device_detach(dev);
731 break;
732 case CS_EVENT_CARD_INSERTION:
733 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
734 fmvj18x_config(link);
735 break;
736 case CS_EVENT_PM_SUSPEND:
737 link->state |= DEV_SUSPEND; 694 link->state |= DEV_SUSPEND;
738 /* Fall through... */
739 case CS_EVENT_RESET_PHYSICAL:
740 if (link->state & DEV_CONFIG) { 695 if (link->state & DEV_CONFIG) {
741 if (link->open) 696 if (link->open)
742 netif_device_detach(dev); 697 netif_device_detach(dev);
743 pcmcia_release_configuration(link->handle); 698 pcmcia_release_configuration(link->handle);
744 } 699 }
745 break; 700
746 case CS_EVENT_PM_RESUME: 701
702 return 0;
703}
704
705static int fmvj18x_resume(struct pcmcia_device *p_dev)
706{
707 dev_link_t *link = dev_to_instance(p_dev);
708 struct net_device *dev = link->priv;
709
747 link->state &= ~DEV_SUSPEND; 710 link->state &= ~DEV_SUSPEND;
748 /* Fall through... */
749 case CS_EVENT_CARD_RESET:
750 if (link->state & DEV_CONFIG) { 711 if (link->state & DEV_CONFIG) {
751 pcmcia_request_configuration(link->handle, &link->conf); 712 pcmcia_request_configuration(link->handle, &link->conf);
752 if (link->open) { 713 if (link->open) {
753 fjn_reset(dev); 714 fjn_reset(dev);
754 netif_device_attach(dev); 715 netif_device_attach(dev);
755 } 716 }
756 } 717 }
757 break; 718
758 } 719 return 0;
759 return 0; 720}
760} /* fmvj18x_event */ 721
722/*====================================================================*/
761 723
762static struct pcmcia_device_id fmvj18x_ids[] = { 724static struct pcmcia_device_id fmvj18x_ids[] = {
763 PCMCIA_DEVICE_MANF_CARD(0x0004, 0x0004), 725 PCMCIA_DEVICE_MANF_CARD(0x0004, 0x0004),
@@ -789,10 +751,11 @@ static struct pcmcia_driver fmvj18x_cs_driver = {
789 .drv = { 751 .drv = {
790 .name = "fmvj18x_cs", 752 .name = "fmvj18x_cs",
791 }, 753 },
792 .attach = fmvj18x_attach, 754 .probe = fmvj18x_attach,
793 .event = fmvj18x_event, 755 .remove = fmvj18x_detach,
794 .detach = fmvj18x_detach,
795 .id_table = fmvj18x_ids, 756 .id_table = fmvj18x_ids,
757 .suspend = fmvj18x_suspend,
758 .resume = fmvj18x_resume,
796}; 759};
797 760
798static int __init init_fmvj18x_cs(void) 761static int __init init_fmvj18x_cs(void)
@@ -803,7 +766,6 @@ static int __init init_fmvj18x_cs(void)
803static void __exit exit_fmvj18x_cs(void) 766static void __exit exit_fmvj18x_cs(void)
804{ 767{
805 pcmcia_unregister_driver(&fmvj18x_cs_driver); 768 pcmcia_unregister_driver(&fmvj18x_cs_driver);
806 BUG_ON(dev_list != NULL);
807} 769}
808 770
809module_init(init_fmvj18x_cs); 771module_init(init_fmvj18x_cs);
diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c
index b6c140eb9799..b9c7e39576f5 100644
--- a/drivers/net/pcmcia/ibmtr_cs.c
+++ b/drivers/net/pcmcia/ibmtr_cs.c
@@ -108,15 +108,7 @@ MODULE_LICENSE("GPL");
108static void ibmtr_config(dev_link_t *link); 108static void ibmtr_config(dev_link_t *link);
109static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase); 109static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase);
110static void ibmtr_release(dev_link_t *link); 110static void ibmtr_release(dev_link_t *link);
111static int ibmtr_event(event_t event, int priority, 111static void ibmtr_detach(struct pcmcia_device *p_dev);
112 event_callback_args_t *args);
113
114static dev_info_t dev_info = "ibmtr_cs";
115
116static dev_link_t *ibmtr_attach(void);
117static void ibmtr_detach(dev_link_t *);
118
119static dev_link_t *dev_list;
120 112
121/*====================================================================*/ 113/*====================================================================*/
122 114
@@ -146,25 +138,23 @@ static struct ethtool_ops netdev_ethtool_ops = {
146 138
147======================================================================*/ 139======================================================================*/
148 140
149static dev_link_t *ibmtr_attach(void) 141static int ibmtr_attach(struct pcmcia_device *p_dev)
150{ 142{
151 ibmtr_dev_t *info; 143 ibmtr_dev_t *info;
152 dev_link_t *link; 144 dev_link_t *link;
153 struct net_device *dev; 145 struct net_device *dev;
154 client_reg_t client_reg;
155 int ret;
156 146
157 DEBUG(0, "ibmtr_attach()\n"); 147 DEBUG(0, "ibmtr_attach()\n");
158 148
159 /* Create new token-ring device */ 149 /* Create new token-ring device */
160 info = kmalloc(sizeof(*info), GFP_KERNEL); 150 info = kmalloc(sizeof(*info), GFP_KERNEL);
161 if (!info) return NULL; 151 if (!info) return -ENOMEM;
162 memset(info,0,sizeof(*info)); 152 memset(info,0,sizeof(*info));
163 dev = alloc_trdev(sizeof(struct tok_info)); 153 dev = alloc_trdev(sizeof(struct tok_info));
164 if (!dev) { 154 if (!dev) {
165 kfree(info); 155 kfree(info);
166 return NULL; 156 return -ENOMEM;
167 } 157 }
168 158
169 link = &info->link; 159 link = &info->link;
170 link->priv = info; 160 link->priv = info;
@@ -185,25 +175,13 @@ static dev_link_t *ibmtr_attach(void)
185 175
186 SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); 176 SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
187 177
188 /* Register with Card Services */ 178 link->handle = p_dev;
189 link->next = dev_list; 179 p_dev->instance = link;
190 dev_list = link;
191 client_reg.dev_info = &dev_info;
192 client_reg.Version = 0x0210;
193 client_reg.event_callback_args.client_data = link;
194 ret = pcmcia_register_client(&link->handle, &client_reg);
195 if (ret != 0) {
196 cs_error(link->handle, RegisterClient, ret);
197 goto out_detach;
198 }
199 180
200out: 181 link->state |= DEV_PRESENT;
201 return link; 182 ibmtr_config(link);
202 183
203out_detach: 184 return 0;
204 ibmtr_detach(link);
205 link = NULL;
206 goto out;
207} /* ibmtr_attach */ 185} /* ibmtr_attach */
208 186
209/*====================================================================== 187/*======================================================================
@@ -215,22 +193,14 @@ out_detach:
215 193
216======================================================================*/ 194======================================================================*/
217 195
218static void ibmtr_detach(dev_link_t *link) 196static void ibmtr_detach(struct pcmcia_device *p_dev)
219{ 197{
198 dev_link_t *link = dev_to_instance(p_dev);
220 struct ibmtr_dev_t *info = link->priv; 199 struct ibmtr_dev_t *info = link->priv;
221 dev_link_t **linkp; 200 struct net_device *dev = info->dev;
222 struct net_device *dev;
223 201
224 DEBUG(0, "ibmtr_detach(0x%p)\n", link); 202 DEBUG(0, "ibmtr_detach(0x%p)\n", link);
225 203
226 /* Locate device structure */
227 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
228 if (*linkp == link) break;
229 if (*linkp == NULL)
230 return;
231
232 dev = info->dev;
233
234 if (link->dev) 204 if (link->dev)
235 unregister_netdev(dev); 205 unregister_netdev(dev);
236 206
@@ -241,13 +211,8 @@ static void ibmtr_detach(dev_link_t *link)
241 if (link->state & DEV_CONFIG) 211 if (link->state & DEV_CONFIG)
242 ibmtr_release(link); 212 ibmtr_release(link);
243 213
244 if (link->handle)
245 pcmcia_deregister_client(link->handle);
246
247 /* Unlink device structure, free bits */
248 *linkp = link->next;
249 free_netdev(dev); 214 free_netdev(dev);
250 kfree(info); 215 kfree(info);
251} /* ibmtr_detach */ 216} /* ibmtr_detach */
252 217
253/*====================================================================== 218/*======================================================================
@@ -401,63 +366,40 @@ static void ibmtr_release(dev_link_t *link)
401 link->state &= ~DEV_CONFIG; 366 link->state &= ~DEV_CONFIG;
402} 367}
403 368
404/*====================================================================== 369static int ibmtr_suspend(struct pcmcia_device *p_dev)
370{
371 dev_link_t *link = dev_to_instance(p_dev);
372 ibmtr_dev_t *info = link->priv;
373 struct net_device *dev = info->dev;
405 374
406 The card status event handler. Mostly, this schedules other 375 link->state |= DEV_SUSPEND;
407 stuff to run after an event is received. A CARD_REMOVAL event 376 if (link->state & DEV_CONFIG) {
408 also sets some flags to discourage the net drivers from trying 377 if (link->open)
409 to talk to the card any more. 378 netif_device_detach(dev);
379 pcmcia_release_configuration(link->handle);
380 }
410 381
411======================================================================*/ 382 return 0;
383}
412 384
413static int ibmtr_event(event_t event, int priority, 385static int ibmtr_resume(struct pcmcia_device *p_dev)
414 event_callback_args_t *args)
415{ 386{
416 dev_link_t *link = args->client_data; 387 dev_link_t *link = dev_to_instance(p_dev);
417 ibmtr_dev_t *info = link->priv; 388 ibmtr_dev_t *info = link->priv;
418 struct net_device *dev = info->dev; 389 struct net_device *dev = info->dev;
419 390
420 DEBUG(1, "ibmtr_event(0x%06x)\n", event); 391 link->state &= ~DEV_SUSPEND;
421
422 switch (event) {
423 case CS_EVENT_CARD_REMOVAL:
424 link->state &= ~DEV_PRESENT;
425 if (link->state & DEV_CONFIG) {
426 /* set flag to bypass normal interrupt code */
427 struct tok_info *priv = netdev_priv(dev);
428 priv->sram_phys |= 1;
429 netif_device_detach(dev);
430 }
431 break;
432 case CS_EVENT_CARD_INSERTION:
433 link->state |= DEV_PRESENT;
434 ibmtr_config(link);
435 break;
436 case CS_EVENT_PM_SUSPEND:
437 link->state |= DEV_SUSPEND;
438 /* Fall through... */
439 case CS_EVENT_RESET_PHYSICAL:
440 if (link->state & DEV_CONFIG) { 392 if (link->state & DEV_CONFIG) {
441 if (link->open) 393 pcmcia_request_configuration(link->handle, &link->conf);
442 netif_device_detach(dev); 394 if (link->open) {
443 pcmcia_release_configuration(link->handle); 395 ibmtr_probe(dev); /* really? */
396 netif_device_attach(dev);
397 }
444 } 398 }
445 break; 399
446 case CS_EVENT_PM_RESUME: 400 return 0;
447 link->state &= ~DEV_SUSPEND; 401}
448 /* Fall through... */ 402
449 case CS_EVENT_CARD_RESET:
450 if (link->state & DEV_CONFIG) {
451 pcmcia_request_configuration(link->handle, &link->conf);
452 if (link->open) {
453 ibmtr_probe(dev); /* really? */
454 netif_device_attach(dev);
455 }
456 }
457 break;
458 }
459 return 0;
460} /* ibmtr_event */
461 403
462/*====================================================================*/ 404/*====================================================================*/
463 405
@@ -514,10 +456,11 @@ static struct pcmcia_driver ibmtr_cs_driver = {
514 .drv = { 456 .drv = {
515 .name = "ibmtr_cs", 457 .name = "ibmtr_cs",
516 }, 458 },
517 .attach = ibmtr_attach, 459 .probe = ibmtr_attach,
518 .event = ibmtr_event, 460 .remove = ibmtr_detach,
519 .detach = ibmtr_detach,
520 .id_table = ibmtr_ids, 461 .id_table = ibmtr_ids,
462 .suspend = ibmtr_suspend,
463 .resume = ibmtr_resume,
521}; 464};
522 465
523static int __init init_ibmtr_cs(void) 466static int __init init_ibmtr_cs(void)
@@ -528,7 +471,6 @@ static int __init init_ibmtr_cs(void)
528static void __exit exit_ibmtr_cs(void) 471static void __exit exit_ibmtr_cs(void)
529{ 472{
530 pcmcia_unregister_driver(&ibmtr_cs_driver); 473 pcmcia_unregister_driver(&ibmtr_cs_driver);
531 BUG_ON(dev_list != NULL);
532} 474}
533 475
534module_init(init_ibmtr_cs); 476module_init(init_ibmtr_cs);
diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c
index 980d7e5d66cb..4a232254a497 100644
--- a/drivers/net/pcmcia/nmclan_cs.c
+++ b/drivers/net/pcmcia/nmclan_cs.c
@@ -388,9 +388,6 @@ static char *version =
388DRV_NAME " " DRV_VERSION " (Roger C. Pao)"; 388DRV_NAME " " DRV_VERSION " (Roger C. Pao)";
389#endif 389#endif
390 390
391static dev_info_t dev_info="nmclan_cs";
392static dev_link_t *dev_list;
393
394static char *if_names[]={ 391static char *if_names[]={
395 "Auto", "10baseT", "BNC", 392 "Auto", "10baseT", "BNC",
396}; 393};
@@ -422,8 +419,6 @@ Function Prototypes
422 419
423static void nmclan_config(dev_link_t *link); 420static void nmclan_config(dev_link_t *link);
424static void nmclan_release(dev_link_t *link); 421static void nmclan_release(dev_link_t *link);
425static int nmclan_event(event_t event, int priority,
426 event_callback_args_t *args);
427 422
428static void nmclan_reset(struct net_device *dev); 423static void nmclan_reset(struct net_device *dev);
429static int mace_config(struct net_device *dev, struct ifmap *map); 424static int mace_config(struct net_device *dev, struct ifmap *map);
@@ -439,8 +434,7 @@ static void set_multicast_list(struct net_device *dev);
439static struct ethtool_ops netdev_ethtool_ops; 434static struct ethtool_ops netdev_ethtool_ops;
440 435
441 436
442static dev_link_t *nmclan_attach(void); 437static void nmclan_detach(struct pcmcia_device *p_dev);
443static void nmclan_detach(dev_link_t *);
444 438
445/* ---------------------------------------------------------------------------- 439/* ----------------------------------------------------------------------------
446nmclan_attach 440nmclan_attach
@@ -449,13 +443,11 @@ nmclan_attach
449 Services. 443 Services.
450---------------------------------------------------------------------------- */ 444---------------------------------------------------------------------------- */
451 445
452static dev_link_t *nmclan_attach(void) 446static int nmclan_attach(struct pcmcia_device *p_dev)
453{ 447{
454 mace_private *lp; 448 mace_private *lp;
455 dev_link_t *link; 449 dev_link_t *link;
456 struct net_device *dev; 450 struct net_device *dev;
457 client_reg_t client_reg;
458 int ret;
459 451
460 DEBUG(0, "nmclan_attach()\n"); 452 DEBUG(0, "nmclan_attach()\n");
461 DEBUG(1, "%s\n", rcsid); 453 DEBUG(1, "%s\n", rcsid);
@@ -463,7 +455,7 @@ static dev_link_t *nmclan_attach(void)
463 /* Create new ethernet device */ 455 /* Create new ethernet device */
464 dev = alloc_etherdev(sizeof(mace_private)); 456 dev = alloc_etherdev(sizeof(mace_private));
465 if (!dev) 457 if (!dev)
466 return NULL; 458 return -ENOMEM;
467 lp = netdev_priv(dev); 459 lp = netdev_priv(dev);
468 link = &lp->link; 460 link = &lp->link;
469 link->priv = dev; 461 link->priv = dev;
@@ -497,20 +489,13 @@ static dev_link_t *nmclan_attach(void)
497 dev->watchdog_timeo = TX_TIMEOUT; 489 dev->watchdog_timeo = TX_TIMEOUT;
498#endif 490#endif
499 491
500 /* Register with Card Services */ 492 link->handle = p_dev;
501 link->next = dev_list; 493 p_dev->instance = link;
502 dev_list = link; 494
503 client_reg.dev_info = &dev_info; 495 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
504 client_reg.Version = 0x0210; 496 nmclan_config(link);
505 client_reg.event_callback_args.client_data = link;
506 ret = pcmcia_register_client(&link->handle, &client_reg);
507 if (ret != 0) {
508 cs_error(link->handle, RegisterClient, ret);
509 nmclan_detach(link);
510 return NULL;
511 }
512 497
513 return link; 498 return 0;
514} /* nmclan_attach */ 499} /* nmclan_attach */
515 500
516/* ---------------------------------------------------------------------------- 501/* ----------------------------------------------------------------------------
@@ -521,30 +506,19 @@ nmclan_detach
521 when the device is released. 506 when the device is released.
522---------------------------------------------------------------------------- */ 507---------------------------------------------------------------------------- */
523 508
524static void nmclan_detach(dev_link_t *link) 509static void nmclan_detach(struct pcmcia_device *p_dev)
525{ 510{
511 dev_link_t *link = dev_to_instance(p_dev);
526 struct net_device *dev = link->priv; 512 struct net_device *dev = link->priv;
527 dev_link_t **linkp;
528 513
529 DEBUG(0, "nmclan_detach(0x%p)\n", link); 514 DEBUG(0, "nmclan_detach(0x%p)\n", link);
530 515
531 /* Locate device structure */
532 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
533 if (*linkp == link) break;
534 if (*linkp == NULL)
535 return;
536
537 if (link->dev) 516 if (link->dev)
538 unregister_netdev(dev); 517 unregister_netdev(dev);
539 518
540 if (link->state & DEV_CONFIG) 519 if (link->state & DEV_CONFIG)
541 nmclan_release(link); 520 nmclan_release(link);
542 521
543 if (link->handle)
544 pcmcia_deregister_client(link->handle);
545
546 /* Unlink device structure, free bits */
547 *linkp = link->next;
548 free_netdev(dev); 522 free_netdev(dev);
549} /* nmclan_detach */ 523} /* nmclan_detach */
550 524
@@ -801,59 +775,39 @@ static void nmclan_release(dev_link_t *link)
801 link->state &= ~DEV_CONFIG; 775 link->state &= ~DEV_CONFIG;
802} 776}
803 777
804/* ---------------------------------------------------------------------------- 778static int nmclan_suspend(struct pcmcia_device *p_dev)
805nmclan_event
806 The card status event handler. Mostly, this schedules other
807 stuff to run after an event is received. A CARD_REMOVAL event
808 also sets some flags to discourage the net drivers from trying
809 to talk to the card any more.
810---------------------------------------------------------------------------- */
811static int nmclan_event(event_t event, int priority,
812 event_callback_args_t *args)
813{ 779{
814 dev_link_t *link = args->client_data; 780 dev_link_t *link = dev_to_instance(p_dev);
815 struct net_device *dev = link->priv; 781 struct net_device *dev = link->priv;
782
783 link->state |= DEV_SUSPEND;
784 if (link->state & DEV_CONFIG) {
785 if (link->open)
786 netif_device_detach(dev);
787 pcmcia_release_configuration(link->handle);
788 }
816 789
817 DEBUG(1, "nmclan_event(0x%06x)\n", event);
818 790
819 switch (event) { 791 return 0;
820 case CS_EVENT_CARD_REMOVAL: 792}
821 link->state &= ~DEV_PRESENT; 793
822 if (link->state & DEV_CONFIG) 794static int nmclan_resume(struct pcmcia_device *p_dev)
823 netif_device_detach(dev); 795{
824 break; 796 dev_link_t *link = dev_to_instance(p_dev);
825 case CS_EVENT_CARD_INSERTION: 797 struct net_device *dev = link->priv;
826 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 798
827 nmclan_config(link); 799 link->state &= ~DEV_SUSPEND;
828 break; 800 if (link->state & DEV_CONFIG) {
829 case CS_EVENT_PM_SUSPEND: 801 pcmcia_request_configuration(link->handle, &link->conf);
830 link->state |= DEV_SUSPEND; 802 if (link->open) {
831 /* Fall through... */ 803 nmclan_reset(dev);
832 case CS_EVENT_RESET_PHYSICAL: 804 netif_device_attach(dev);
833 if (link->state & DEV_CONFIG) { 805 }
834 if (link->open)
835 netif_device_detach(dev);
836 pcmcia_release_configuration(link->handle);
837 }
838 break;
839 case CS_EVENT_PM_RESUME:
840 link->state &= ~DEV_SUSPEND;
841 /* Fall through... */
842 case CS_EVENT_CARD_RESET:
843 if (link->state & DEV_CONFIG) {
844 pcmcia_request_configuration(link->handle, &link->conf);
845 if (link->open) {
846 nmclan_reset(dev);
847 netif_device_attach(dev);
848 } 806 }
849 } 807
850 break; 808 return 0;
851 case CS_EVENT_RESET_REQUEST: 809}
852 return 1; 810
853 break;
854 }
855 return 0;
856} /* nmclan_event */
857 811
858/* ---------------------------------------------------------------------------- 812/* ----------------------------------------------------------------------------
859nmclan_reset 813nmclan_reset
@@ -1681,10 +1635,11 @@ static struct pcmcia_driver nmclan_cs_driver = {
1681 .drv = { 1635 .drv = {
1682 .name = "nmclan_cs", 1636 .name = "nmclan_cs",
1683 }, 1637 },
1684 .attach = nmclan_attach, 1638 .probe = nmclan_attach,
1685 .event = nmclan_event, 1639 .remove = nmclan_detach,
1686 .detach = nmclan_detach,
1687 .id_table = nmclan_ids, 1640 .id_table = nmclan_ids,
1641 .suspend = nmclan_suspend,
1642 .resume = nmclan_resume,
1688}; 1643};
1689 1644
1690static int __init init_nmclan_cs(void) 1645static int __init init_nmclan_cs(void)
@@ -1695,7 +1650,6 @@ static int __init init_nmclan_cs(void)
1695static void __exit exit_nmclan_cs(void) 1650static void __exit exit_nmclan_cs(void)
1696{ 1651{
1697 pcmcia_unregister_driver(&nmclan_cs_driver); 1652 pcmcia_unregister_driver(&nmclan_cs_driver);
1698 BUG_ON(dev_list != NULL);
1699} 1653}
1700 1654
1701module_init(init_nmclan_cs); 1655module_init(init_nmclan_cs);
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index 818c185d6438..d85b758f3efa 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -105,8 +105,6 @@ module_param_array(hw_addr, int, NULL, 0);
105static void mii_phy_probe(struct net_device *dev); 105static void mii_phy_probe(struct net_device *dev);
106static void pcnet_config(dev_link_t *link); 106static void pcnet_config(dev_link_t *link);
107static void pcnet_release(dev_link_t *link); 107static void pcnet_release(dev_link_t *link);
108static int pcnet_event(event_t event, int priority,
109 event_callback_args_t *args);
110static int pcnet_open(struct net_device *dev); 108static int pcnet_open(struct net_device *dev);
111static int pcnet_close(struct net_device *dev); 109static int pcnet_close(struct net_device *dev);
112static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); 110static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
@@ -120,11 +118,9 @@ static int setup_shmem_window(dev_link_t *link, int start_pg,
120static int setup_dma_config(dev_link_t *link, int start_pg, 118static int setup_dma_config(dev_link_t *link, int start_pg,
121 int stop_pg); 119 int stop_pg);
122 120
123static dev_link_t *pcnet_attach(void); 121static void pcnet_detach(struct pcmcia_device *p_dev);
124static void pcnet_detach(dev_link_t *);
125 122
126static dev_info_t dev_info = "pcnet_cs"; 123static dev_info_t dev_info = "pcnet_cs";
127static dev_link_t *dev_list;
128 124
129/*====================================================================*/ 125/*====================================================================*/
130 126
@@ -244,19 +240,17 @@ static inline pcnet_dev_t *PRIV(struct net_device *dev)
244 240
245======================================================================*/ 241======================================================================*/
246 242
247static dev_link_t *pcnet_attach(void) 243static int pcnet_probe(struct pcmcia_device *p_dev)
248{ 244{
249 pcnet_dev_t *info; 245 pcnet_dev_t *info;
250 dev_link_t *link; 246 dev_link_t *link;
251 struct net_device *dev; 247 struct net_device *dev;
252 client_reg_t client_reg;
253 int ret;
254 248
255 DEBUG(0, "pcnet_attach()\n"); 249 DEBUG(0, "pcnet_attach()\n");
256 250
257 /* Create new ethernet device */ 251 /* Create new ethernet device */
258 dev = __alloc_ei_netdev(sizeof(pcnet_dev_t)); 252 dev = __alloc_ei_netdev(sizeof(pcnet_dev_t));
259 if (!dev) return NULL; 253 if (!dev) return -ENOMEM;
260 info = PRIV(dev); 254 info = PRIV(dev);
261 link = &info->link; 255 link = &info->link;
262 link->priv = dev; 256 link->priv = dev;
@@ -271,20 +265,13 @@ static dev_link_t *pcnet_attach(void)
271 dev->stop = &pcnet_close; 265 dev->stop = &pcnet_close;
272 dev->set_config = &set_config; 266 dev->set_config = &set_config;
273 267
274 /* Register with Card Services */ 268 link->handle = p_dev;
275 link->next = dev_list; 269 p_dev->instance = link;
276 dev_list = link;
277 client_reg.dev_info = &dev_info;
278 client_reg.Version = 0x0210;
279 client_reg.event_callback_args.client_data = link;
280 ret = pcmcia_register_client(&link->handle, &client_reg);
281 if (ret != CS_SUCCESS) {
282 cs_error(link->handle, RegisterClient, ret);
283 pcnet_detach(link);
284 return NULL;
285 }
286 270
287 return link; 271 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
272 pcnet_config(link);
273
274 return 0;
288} /* pcnet_attach */ 275} /* pcnet_attach */
289 276
290/*====================================================================== 277/*======================================================================
@@ -296,31 +283,20 @@ static dev_link_t *pcnet_attach(void)
296 283
297======================================================================*/ 284======================================================================*/
298 285
299static void pcnet_detach(dev_link_t *link) 286static void pcnet_detach(struct pcmcia_device *p_dev)
300{ 287{
301 struct net_device *dev = link->priv; 288 dev_link_t *link = dev_to_instance(p_dev);
302 dev_link_t **linkp; 289 struct net_device *dev = link->priv;
303
304 DEBUG(0, "pcnet_detach(0x%p)\n", link);
305 290
306 /* Locate device structure */ 291 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 292
312 if (link->dev) 293 if (link->dev)
313 unregister_netdev(dev); 294 unregister_netdev(dev);
314 295
315 if (link->state & DEV_CONFIG) 296 if (link->state & DEV_CONFIG)
316 pcnet_release(link); 297 pcnet_release(link);
317
318 if (link->handle)
319 pcmcia_deregister_client(link->handle);
320 298
321 /* Unlink device structure, free bits */ 299 free_netdev(dev);
322 *linkp = link->next;
323 free_netdev(dev);
324} /* pcnet_detach */ 300} /* pcnet_detach */
325 301
326/*====================================================================== 302/*======================================================================
@@ -780,50 +756,39 @@ static void pcnet_release(dev_link_t *link)
780 756
781======================================================================*/ 757======================================================================*/
782 758
783static int pcnet_event(event_t event, int priority, 759static int pcnet_suspend(struct pcmcia_device *p_dev)
784 event_callback_args_t *args)
785{ 760{
786 dev_link_t *link = args->client_data; 761 dev_link_t *link = dev_to_instance(p_dev);
787 struct net_device *dev = link->priv; 762 struct net_device *dev = link->priv;
788 763
789 DEBUG(2, "pcnet_event(0x%06x)\n", event);
790
791 switch (event) {
792 case CS_EVENT_CARD_REMOVAL:
793 link->state &= ~DEV_PRESENT;
794 if (link->state & DEV_CONFIG)
795 netif_device_detach(dev);
796 break;
797 case CS_EVENT_CARD_INSERTION:
798 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
799 pcnet_config(link);
800 break;
801 case CS_EVENT_PM_SUSPEND:
802 link->state |= DEV_SUSPEND; 764 link->state |= DEV_SUSPEND;
803 /* Fall through... */
804 case CS_EVENT_RESET_PHYSICAL:
805 if (link->state & DEV_CONFIG) { 765 if (link->state & DEV_CONFIG) {
806 if (link->open) 766 if (link->open)
807 netif_device_detach(dev); 767 netif_device_detach(dev);
808 pcmcia_release_configuration(link->handle); 768 pcmcia_release_configuration(link->handle);
809 } 769 }
810 break; 770
811 case CS_EVENT_PM_RESUME: 771 return 0;
772}
773
774static int pcnet_resume(struct pcmcia_device *p_dev)
775{
776 dev_link_t *link = dev_to_instance(p_dev);
777 struct net_device *dev = link->priv;
778
812 link->state &= ~DEV_SUSPEND; 779 link->state &= ~DEV_SUSPEND;
813 /* Fall through... */
814 case CS_EVENT_CARD_RESET:
815 if (link->state & DEV_CONFIG) { 780 if (link->state & DEV_CONFIG) {
816 pcmcia_request_configuration(link->handle, &link->conf); 781 pcmcia_request_configuration(link->handle, &link->conf);
817 if (link->open) { 782 if (link->open) {
818 pcnet_reset_8390(dev); 783 pcnet_reset_8390(dev);
819 NS8390_init(dev, 1); 784 NS8390_init(dev, 1);
820 netif_device_attach(dev); 785 netif_device_attach(dev);
821 } 786 }
822 } 787 }
823 break; 788
824 } 789 return 0;
825 return 0; 790}
826} /* pcnet_event */ 791
827 792
828/*====================================================================== 793/*======================================================================
829 794
@@ -1844,11 +1809,12 @@ static struct pcmcia_driver pcnet_driver = {
1844 .drv = { 1809 .drv = {
1845 .name = "pcnet_cs", 1810 .name = "pcnet_cs",
1846 }, 1811 },
1847 .attach = pcnet_attach, 1812 .probe = pcnet_probe,
1848 .event = pcnet_event, 1813 .remove = pcnet_detach,
1849 .detach = pcnet_detach,
1850 .owner = THIS_MODULE, 1814 .owner = THIS_MODULE,
1851 .id_table = pcnet_ids, 1815 .id_table = pcnet_ids,
1816 .suspend = pcnet_suspend,
1817 .resume = pcnet_resume,
1852}; 1818};
1853 1819
1854static int __init init_pcnet_cs(void) 1820static int __init init_pcnet_cs(void)
@@ -1860,7 +1826,6 @@ static void __exit exit_pcnet_cs(void)
1860{ 1826{
1861 DEBUG(0, "pcnet_cs: unloading\n"); 1827 DEBUG(0, "pcnet_cs: unloading\n");
1862 pcmcia_unregister_driver(&pcnet_driver); 1828 pcmcia_unregister_driver(&pcnet_driver);
1863 BUG_ON(dev_list != NULL);
1864} 1829}
1865 1830
1866module_init(init_pcnet_cs); 1831module_init(init_pcnet_cs);
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index c7cca842e5ee..0122415dfeef 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -102,10 +102,6 @@ static const char *version =
102 currently have room for another Tx packet. */ 102 currently have room for another Tx packet. */
103#define MEMORY_WAIT_TIME 8 103#define MEMORY_WAIT_TIME 8
104 104
105static dev_info_t dev_info = "smc91c92_cs";
106
107static dev_link_t *dev_list;
108
109struct smc_private { 105struct smc_private {
110 dev_link_t link; 106 dev_link_t link;
111 spinlock_t lock; 107 spinlock_t lock;
@@ -281,12 +277,9 @@ enum RxCfg { RxAllMulti = 0x0004, RxPromisc = 0x0002,
281 277
282/*====================================================================*/ 278/*====================================================================*/
283 279
284static dev_link_t *smc91c92_attach(void); 280static void smc91c92_detach(struct pcmcia_device *p_dev);
285static void smc91c92_detach(dev_link_t *);
286static void smc91c92_config(dev_link_t *link); 281static void smc91c92_config(dev_link_t *link);
287static void smc91c92_release(dev_link_t *link); 282static void smc91c92_release(dev_link_t *link);
288static int smc91c92_event(event_t event, int priority,
289 event_callback_args_t *args);
290 283
291static int smc_open(struct net_device *dev); 284static int smc_open(struct net_device *dev);
292static int smc_close(struct net_device *dev); 285static int smc_close(struct net_device *dev);
@@ -315,20 +308,18 @@ static struct ethtool_ops ethtool_ops;
315 308
316======================================================================*/ 309======================================================================*/
317 310
318static dev_link_t *smc91c92_attach(void) 311static int smc91c92_attach(struct pcmcia_device *p_dev)
319{ 312{
320 client_reg_t client_reg;
321 struct smc_private *smc; 313 struct smc_private *smc;
322 dev_link_t *link; 314 dev_link_t *link;
323 struct net_device *dev; 315 struct net_device *dev;
324 int ret;
325 316
326 DEBUG(0, "smc91c92_attach()\n"); 317 DEBUG(0, "smc91c92_attach()\n");
327 318
328 /* Create new ethernet device */ 319 /* Create new ethernet device */
329 dev = alloc_etherdev(sizeof(struct smc_private)); 320 dev = alloc_etherdev(sizeof(struct smc_private));
330 if (!dev) 321 if (!dev)
331 return NULL; 322 return -ENOMEM;
332 smc = netdev_priv(dev); 323 smc = netdev_priv(dev);
333 link = &smc->link; 324 link = &smc->link;
334 link->priv = dev; 325 link->priv = dev;
@@ -366,20 +357,13 @@ static dev_link_t *smc91c92_attach(void)
366 smc->mii_if.phy_id_mask = 0x1f; 357 smc->mii_if.phy_id_mask = 0x1f;
367 smc->mii_if.reg_num_mask = 0x1f; 358 smc->mii_if.reg_num_mask = 0x1f;
368 359
369 /* Register with Card Services */ 360 link->handle = p_dev;
370 link->next = dev_list; 361 p_dev->instance = link;
371 dev_list = link; 362
372 client_reg.dev_info = &dev_info; 363 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
373 client_reg.Version = 0x0210; 364 smc91c92_config(link);
374 client_reg.event_callback_args.client_data = link;
375 ret = pcmcia_register_client(&link->handle, &client_reg);
376 if (ret != 0) {
377 cs_error(link->handle, RegisterClient, ret);
378 smc91c92_detach(link);
379 return NULL;
380 }
381 365
382 return link; 366 return 0;
383} /* smc91c92_attach */ 367} /* smc91c92_attach */
384 368
385/*====================================================================== 369/*======================================================================
@@ -391,30 +375,19 @@ static dev_link_t *smc91c92_attach(void)
391 375
392======================================================================*/ 376======================================================================*/
393 377
394static void smc91c92_detach(dev_link_t *link) 378static void smc91c92_detach(struct pcmcia_device *p_dev)
395{ 379{
380 dev_link_t *link = dev_to_instance(p_dev);
396 struct net_device *dev = link->priv; 381 struct net_device *dev = link->priv;
397 dev_link_t **linkp;
398 382
399 DEBUG(0, "smc91c92_detach(0x%p)\n", link); 383 DEBUG(0, "smc91c92_detach(0x%p)\n", link);
400 384
401 /* Locate device structure */
402 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
403 if (*linkp == link) break;
404 if (*linkp == NULL)
405 return;
406
407 if (link->dev) 385 if (link->dev)
408 unregister_netdev(dev); 386 unregister_netdev(dev);
409 387
410 if (link->state & DEV_CONFIG) 388 if (link->state & DEV_CONFIG)
411 smc91c92_release(link); 389 smc91c92_release(link);
412 390
413 if (link->handle)
414 pcmcia_deregister_client(link->handle);
415
416 /* Unlink device structure, free bits */
417 *linkp = link->next;
418 free_netdev(dev); 391 free_netdev(dev);
419} /* smc91c92_detach */ 392} /* smc91c92_detach */
420 393
@@ -895,6 +868,62 @@ free_cfg_mem:
895 return rc; 868 return rc;
896} 869}
897 870
871static int smc91c92_suspend(struct pcmcia_device *p_dev)
872{
873 dev_link_t *link = dev_to_instance(p_dev);
874 struct net_device *dev = link->priv;
875
876 link->state |= DEV_SUSPEND;
877 if (link->state & DEV_CONFIG) {
878 if (link->open)
879 netif_device_detach(dev);
880 pcmcia_release_configuration(link->handle);
881 }
882
883 return 0;
884}
885
886static int smc91c92_resume(struct pcmcia_device *p_dev)
887{
888 dev_link_t *link = dev_to_instance(p_dev);
889 struct net_device *dev = link->priv;
890 struct smc_private *smc = netdev_priv(dev);
891 int i;
892
893 link->state &= ~DEV_SUSPEND;
894 if (link->state & DEV_CONFIG) {
895 if ((smc->manfid == MANFID_MEGAHERTZ) &&
896 (smc->cardid == PRODID_MEGAHERTZ_EM3288))
897 mhz_3288_power(link);
898 pcmcia_request_configuration(link->handle, &link->conf);
899 if (smc->manfid == MANFID_MOTOROLA)
900 mot_config(link);
901 if ((smc->manfid == MANFID_OSITECH) &&
902 (smc->cardid != PRODID_OSITECH_SEVEN)) {
903 /* Power up the card and enable interrupts */
904 set_bits(0x0300, dev->base_addr-0x10+OSITECH_AUI_PWR);
905 set_bits(0x0300, dev->base_addr-0x10+OSITECH_RESET_ISR);
906 }
907 if (((smc->manfid == MANFID_OSITECH) &&
908 (smc->cardid == PRODID_OSITECH_SEVEN)) ||
909 ((smc->manfid == MANFID_PSION) &&
910 (smc->cardid == PRODID_PSION_NET100))) {
911 /* Download the Seven of Diamonds firmware */
912 for (i = 0; i < sizeof(__Xilinx7OD); i++) {
913 outb(__Xilinx7OD[i], link->io.BasePort1+2);
914 udelay(50);
915 }
916 }
917 if (link->open) {
918 smc_reset(dev);
919 netif_device_attach(dev);
920 }
921 }
922
923 return 0;
924}
925
926
898/*====================================================================== 927/*======================================================================
899 928
900 This verifies that the chip is some SMC91cXX variant, and returns 929 This verifies that the chip is some SMC91cXX variant, and returns
@@ -935,14 +964,12 @@ static int check_sig(dev_link_t *link)
935 } 964 }
936 965
937 if (width) { 966 if (width) {
938 event_callback_args_t args;
939 printk(KERN_INFO "smc91c92_cs: using 8-bit IO window.\n"); 967 printk(KERN_INFO "smc91c92_cs: using 8-bit IO window.\n");
940 args.client_data = link; 968 smc91c92_suspend(link->handle);
941 smc91c92_event(CS_EVENT_RESET_PHYSICAL, 0, &args);
942 pcmcia_release_io(link->handle, &link->io); 969 pcmcia_release_io(link->handle, &link->io);
943 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; 970 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
944 pcmcia_request_io(link->handle, &link->io); 971 pcmcia_request_io(link->handle, &link->io);
945 smc91c92_event(CS_EVENT_CARD_RESET, 0, &args); 972 smc91c92_resume(link->handle);
946 return check_sig(link); 973 return check_sig(link);
947 } 974 }
948 return -ENODEV; 975 return -ENODEV;
@@ -1172,82 +1199,6 @@ static void smc91c92_release(dev_link_t *link)
1172 1199
1173/*====================================================================== 1200/*======================================================================
1174 1201
1175 The card status event handler. Mostly, this schedules other
1176 stuff to run after an event is received. A CARD_REMOVAL event
1177 also sets some flags to discourage the net drivers from trying
1178 to talk to the card any more.
1179
1180======================================================================*/
1181
1182static int smc91c92_event(event_t event, int priority,
1183 event_callback_args_t *args)
1184{
1185 dev_link_t *link = args->client_data;
1186 struct net_device *dev = link->priv;
1187 struct smc_private *smc = netdev_priv(dev);
1188 int i;
1189
1190 DEBUG(1, "smc91c92_event(0x%06x)\n", event);
1191
1192 switch (event) {
1193 case CS_EVENT_CARD_REMOVAL:
1194 link->state &= ~DEV_PRESENT;
1195 if (link->state & DEV_CONFIG)
1196 netif_device_detach(dev);
1197 break;
1198 case CS_EVENT_CARD_INSERTION:
1199 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
1200 smc91c92_config(link);
1201 break;
1202 case CS_EVENT_PM_SUSPEND:
1203 link->state |= DEV_SUSPEND;
1204 /* Fall through... */
1205 case CS_EVENT_RESET_PHYSICAL:
1206 if (link->state & DEV_CONFIG) {
1207 if (link->open)
1208 netif_device_detach(dev);
1209 pcmcia_release_configuration(link->handle);
1210 }
1211 break;
1212 case CS_EVENT_PM_RESUME:
1213 link->state &= ~DEV_SUSPEND;
1214 /* Fall through... */
1215 case CS_EVENT_CARD_RESET:
1216 if (link->state & DEV_CONFIG) {
1217 if ((smc->manfid == MANFID_MEGAHERTZ) &&
1218 (smc->cardid == PRODID_MEGAHERTZ_EM3288))
1219 mhz_3288_power(link);
1220 pcmcia_request_configuration(link->handle, &link->conf);
1221 if (smc->manfid == MANFID_MOTOROLA)
1222 mot_config(link);
1223 if ((smc->manfid == MANFID_OSITECH) &&
1224 (smc->cardid != PRODID_OSITECH_SEVEN)) {
1225 /* Power up the card and enable interrupts */
1226 set_bits(0x0300, dev->base_addr-0x10+OSITECH_AUI_PWR);
1227 set_bits(0x0300, dev->base_addr-0x10+OSITECH_RESET_ISR);
1228 }
1229 if (((smc->manfid == MANFID_OSITECH) &&
1230 (smc->cardid == PRODID_OSITECH_SEVEN)) ||
1231 ((smc->manfid == MANFID_PSION) &&
1232 (smc->cardid == PRODID_PSION_NET100))) {
1233 /* Download the Seven of Diamonds firmware */
1234 for (i = 0; i < sizeof(__Xilinx7OD); i++) {
1235 outb(__Xilinx7OD[i], link->io.BasePort1+2);
1236 udelay(50);
1237 }
1238 }
1239 if (link->open) {
1240 smc_reset(dev);
1241 netif_device_attach(dev);
1242 }
1243 }
1244 break;
1245 }
1246 return 0;
1247} /* smc91c92_event */
1248
1249/*======================================================================
1250
1251 MII interface support for SMC91cXX based cards 1202 MII interface support for SMC91cXX based cards
1252======================================================================*/ 1203======================================================================*/
1253 1204
@@ -2360,10 +2311,11 @@ static struct pcmcia_driver smc91c92_cs_driver = {
2360 .drv = { 2311 .drv = {
2361 .name = "smc91c92_cs", 2312 .name = "smc91c92_cs",
2362 }, 2313 },
2363 .attach = smc91c92_attach, 2314 .probe = smc91c92_attach,
2364 .event = smc91c92_event, 2315 .remove = smc91c92_detach,
2365 .detach = smc91c92_detach,
2366 .id_table = smc91c92_ids, 2316 .id_table = smc91c92_ids,
2317 .suspend = smc91c92_suspend,
2318 .resume = smc91c92_resume,
2367}; 2319};
2368 2320
2369static int __init init_smc91c92_cs(void) 2321static int __init init_smc91c92_cs(void)
@@ -2374,7 +2326,6 @@ static int __init init_smc91c92_cs(void)
2374static void __exit exit_smc91c92_cs(void) 2326static void __exit exit_smc91c92_cs(void)
2375{ 2327{
2376 pcmcia_unregister_driver(&smc91c92_cs_driver); 2328 pcmcia_unregister_driver(&smc91c92_cs_driver);
2377 BUG_ON(dev_list != NULL);
2378} 2329}
2379 2330
2380module_init(init_smc91c92_cs); 2331module_init(init_smc91c92_cs);
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
index ce143f08638a..049c34b37067 100644
--- a/drivers/net/pcmcia/xirc2ps_cs.c
+++ b/drivers/net/pcmcia/xirc2ps_cs.c
@@ -292,8 +292,6 @@ static void mii_wr(kio_addr_t ioaddr, u_char phyaddr, u_char phyreg,
292static int has_ce2_string(dev_link_t * link); 292static int has_ce2_string(dev_link_t * link);
293static void xirc2ps_config(dev_link_t * link); 293static void xirc2ps_config(dev_link_t * link);
294static void xirc2ps_release(dev_link_t * link); 294static void xirc2ps_release(dev_link_t * link);
295static int xirc2ps_event(event_t event, int priority,
296 event_callback_args_t * args);
297 295
298/**************** 296/****************
299 * The attach() and detach() entry points are used to create and destroy 297 * The attach() and detach() entry points are used to create and destroy
@@ -301,8 +299,7 @@ static int xirc2ps_event(event_t event, int priority,
301 * needed to manage one actual PCMCIA card. 299 * needed to manage one actual PCMCIA card.
302 */ 300 */
303 301
304static dev_link_t *xirc2ps_attach(void); 302static void xirc2ps_detach(struct pcmcia_device *p_dev);
305static void xirc2ps_detach(dev_link_t *);
306 303
307/**************** 304/****************
308 * You'll also need to prototype all the functions that will actually 305 * You'll also need to prototype all the functions that will actually
@@ -313,14 +310,6 @@ static void xirc2ps_detach(dev_link_t *);
313 310
314static irqreturn_t xirc2ps_interrupt(int irq, void *dev_id, struct pt_regs *regs); 311static irqreturn_t xirc2ps_interrupt(int irq, void *dev_id, struct pt_regs *regs);
315 312
316/*
317 * The dev_info variable is the "key" that is used to match up this
318 * device driver with appropriate cards, through the card configuration
319 * database.
320 */
321
322static dev_info_t dev_info = "xirc2ps_cs";
323
324/**************** 313/****************
325 * A linked list of "instances" of the device. Each actual 314 * A linked list of "instances" of the device. Each actual
326 * PCMCIA card corresponds to one device instance, and is described 315 * PCMCIA card corresponds to one device instance, and is described
@@ -331,15 +320,7 @@ static dev_info_t dev_info = "xirc2ps_cs";
331 * device numbers are used to derive the corresponding array index. 320 * device numbers are used to derive the corresponding array index.
332 */ 321 */
333 322
334static dev_link_t *dev_list;
335
336/**************** 323/****************
337 * A dev_link_t structure has fields for most things that are needed
338 * to keep track of a socket, but there will usually be some device
339 * specific information that also needs to be kept track of. The
340 * 'priv' pointer in a dev_link_t structure can be used to point to
341 * a device-specific private data structure, like this.
342 *
343 * A driver needs to provide a dev_node_t structure for each device 324 * A driver needs to provide a dev_node_t structure for each device
344 * on a card. In some cases, there is only one device per card (for 325 * on a card. In some cases, there is only one device per card (for
345 * example, ethernet cards, modems). In other cases, there may be 326 * example, ethernet cards, modems). In other cases, there may be
@@ -571,21 +552,19 @@ mii_wr(kio_addr_t ioaddr, u_char phyaddr, u_char phyreg, unsigned data, int len)
571 * card insertion event. 552 * card insertion event.
572 */ 553 */
573 554
574static dev_link_t * 555static int
575xirc2ps_attach(void) 556xirc2ps_attach(struct pcmcia_device *p_dev)
576{ 557{
577 client_reg_t client_reg;
578 dev_link_t *link; 558 dev_link_t *link;
579 struct net_device *dev; 559 struct net_device *dev;
580 local_info_t *local; 560 local_info_t *local;
581 int err;
582 561
583 DEBUG(0, "attach()\n"); 562 DEBUG(0, "attach()\n");
584 563
585 /* Allocate the device structure */ 564 /* Allocate the device structure */
586 dev = alloc_etherdev(sizeof(local_info_t)); 565 dev = alloc_etherdev(sizeof(local_info_t));
587 if (!dev) 566 if (!dev)
588 return NULL; 567 return -ENOMEM;
589 local = netdev_priv(dev); 568 local = netdev_priv(dev);
590 link = &local->link; 569 link = &local->link;
591 link->priv = dev; 570 link->priv = dev;
@@ -614,19 +593,13 @@ xirc2ps_attach(void)
614 dev->watchdog_timeo = TX_TIMEOUT; 593 dev->watchdog_timeo = TX_TIMEOUT;
615#endif 594#endif
616 595
617 /* Register with Card Services */ 596 link->handle = p_dev;
618 link->next = dev_list; 597 p_dev->instance = link;
619 dev_list = link; 598
620 client_reg.dev_info = &dev_info; 599 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
621 client_reg.Version = 0x0210; 600 xirc2ps_config(link);
622 client_reg.event_callback_args.client_data = link;
623 if ((err = pcmcia_register_client(&link->handle, &client_reg))) {
624 cs_error(link->handle, RegisterClient, err);
625 xirc2ps_detach(link);
626 return NULL;
627 }
628 601
629 return link; 602 return 0;
630} /* xirc2ps_attach */ 603} /* xirc2ps_attach */
631 604
632/**************** 605/****************
@@ -637,40 +610,19 @@ xirc2ps_attach(void)
637 */ 610 */
638 611
639static void 612static void
640xirc2ps_detach(dev_link_t * link) 613xirc2ps_detach(struct pcmcia_device *p_dev)
641{ 614{
615 dev_link_t *link = dev_to_instance(p_dev);
642 struct net_device *dev = link->priv; 616 struct net_device *dev = link->priv;
643 dev_link_t **linkp;
644 617
645 DEBUG(0, "detach(0x%p)\n", link); 618 DEBUG(0, "detach(0x%p)\n", link);
646 619
647 /* Locate device structure */
648 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
649 if (*linkp == link)
650 break;
651 if (!*linkp) {
652 DEBUG(0, "detach(0x%p): dev_link lost\n", link);
653 return;
654 }
655
656 if (link->dev) 620 if (link->dev)
657 unregister_netdev(dev); 621 unregister_netdev(dev);
658 622
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) 623 if (link->state & DEV_CONFIG)
666 xirc2ps_release(link); 624 xirc2ps_release(link);
667 625
668 /* Break the link with Card Services */
669 if (link->handle)
670 pcmcia_deregister_client(link->handle);
671
672 /* Unlink device structure, free it */
673 *linkp = link->next;
674 free_netdev(dev); 626 free_netdev(dev);
675} /* xirc2ps_detach */ 627} /* xirc2ps_detach */
676 628
@@ -1157,67 +1109,41 @@ xirc2ps_release(dev_link_t *link)
1157 1109
1158/*====================================================================*/ 1110/*====================================================================*/
1159 1111
1160/****************
1161 * The card status event handler. Mostly, this schedules other
1162 * stuff to run after an event is received. A CARD_REMOVAL event
1163 * also sets some flags to discourage the net drivers from trying
1164 * to talk to the card any more.
1165 *
1166 * When a CARD_REMOVAL event is received, we immediately set a flag
1167 * to block future accesses to this device. All the functions that
1168 * actually access the device should check this flag to make sure
1169 * the card is still present.
1170 */
1171 1112
1172static int 1113static int xirc2ps_suspend(struct pcmcia_device *p_dev)
1173xirc2ps_event(event_t event, int priority,
1174 event_callback_args_t * args)
1175{ 1114{
1176 dev_link_t *link = args->client_data; 1115 dev_link_t *link = dev_to_instance(p_dev);
1177 struct net_device *dev = link->priv; 1116 struct net_device *dev = link->priv;
1178
1179 DEBUG(0, "event(%d)\n", (int)event);
1180 1117
1181 switch (event) {
1182 case CS_EVENT_REGISTRATION_COMPLETE:
1183 DEBUG(0, "registration complete\n");
1184 break;
1185 case CS_EVENT_CARD_REMOVAL:
1186 link->state &= ~DEV_PRESENT;
1187 if (link->state & DEV_CONFIG)
1188 netif_device_detach(dev);
1189 break;
1190 case CS_EVENT_CARD_INSERTION:
1191 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
1192 xirc2ps_config(link);
1193 break;
1194 case CS_EVENT_PM_SUSPEND:
1195 link->state |= DEV_SUSPEND; 1118 link->state |= DEV_SUSPEND;
1196 /* Fall through... */
1197 case CS_EVENT_RESET_PHYSICAL:
1198 if (link->state & DEV_CONFIG) { 1119 if (link->state & DEV_CONFIG) {
1199 if (link->open) { 1120 if (link->open) {
1200 netif_device_detach(dev); 1121 netif_device_detach(dev);
1201 do_powerdown(dev); 1122 do_powerdown(dev);
1202 } 1123 }
1203 pcmcia_release_configuration(link->handle); 1124 pcmcia_release_configuration(link->handle);
1204 } 1125 }
1205 break; 1126
1206 case CS_EVENT_PM_RESUME: 1127 return 0;
1128}
1129
1130static int xirc2ps_resume(struct pcmcia_device *p_dev)
1131{
1132 dev_link_t *link = dev_to_instance(p_dev);
1133 struct net_device *dev = link->priv;
1134
1207 link->state &= ~DEV_SUSPEND; 1135 link->state &= ~DEV_SUSPEND;
1208 /* Fall through... */
1209 case CS_EVENT_CARD_RESET:
1210 if (link->state & DEV_CONFIG) { 1136 if (link->state & DEV_CONFIG) {
1211 pcmcia_request_configuration(link->handle, &link->conf); 1137 pcmcia_request_configuration(link->handle, &link->conf);
1212 if (link->open) { 1138 if (link->open) {
1213 do_reset(dev,1); 1139 do_reset(dev,1);
1214 netif_device_attach(dev); 1140 netif_device_attach(dev);
1215 } 1141 }
1216 } 1142 }
1217 break; 1143
1218 } 1144 return 0;
1219 return 0; 1145}
1220} /* xirc2ps_event */ 1146
1221 1147
1222/*====================================================================*/ 1148/*====================================================================*/
1223 1149
@@ -2009,10 +1935,11 @@ static struct pcmcia_driver xirc2ps_cs_driver = {
2009 .drv = { 1935 .drv = {
2010 .name = "xirc2ps_cs", 1936 .name = "xirc2ps_cs",
2011 }, 1937 },
2012 .attach = xirc2ps_attach, 1938 .probe = xirc2ps_attach,
2013 .event = xirc2ps_event, 1939 .remove = xirc2ps_detach,
2014 .detach = xirc2ps_detach,
2015 .id_table = xirc2ps_ids, 1940 .id_table = xirc2ps_ids,
1941 .suspend = xirc2ps_suspend,
1942 .resume = xirc2ps_resume,
2016}; 1943};
2017 1944
2018static int __init 1945static int __init
@@ -2025,7 +1952,6 @@ static void __exit
2025exit_xirc2ps_cs(void) 1952exit_xirc2ps_cs(void)
2026{ 1953{
2027 pcmcia_unregister_driver(&xirc2ps_cs_driver); 1954 pcmcia_unregister_driver(&xirc2ps_cs_driver);
2028 BUG_ON(dev_list != NULL);
2029} 1955}
2030 1956
2031module_init(init_xirc2ps_cs); 1957module_init(init_xirc2ps_cs);
diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c
index e328547599dc..a496460ce224 100644
--- a/drivers/net/wireless/airo_cs.c
+++ b/drivers/net/wireless/airo_cs.c
@@ -82,8 +82,6 @@ MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340 PCMCIA cards");
82 82
83static void airo_config(dev_link_t *link); 83static void airo_config(dev_link_t *link);
84static void airo_release(dev_link_t *link); 84static void airo_release(dev_link_t *link);
85static int airo_event(event_t event, int priority,
86 event_callback_args_t *args);
87 85
88/* 86/*
89 The attach() and detach() entry points are used to create and destroy 87 The attach() and detach() entry points are used to create and destroy
@@ -91,8 +89,7 @@ static int airo_event(event_t event, int priority,
91 needed to manage one actual PCMCIA card. 89 needed to manage one actual PCMCIA card.
92*/ 90*/
93 91
94static dev_link_t *airo_attach(void); 92static void airo_detach(struct pcmcia_device *p_dev);
95static void airo_detach(dev_link_t *);
96 93
97/* 94/*
98 You'll also need to prototype all the functions that will actually 95 You'll also need to prototype all the functions that will actually
@@ -102,14 +99,6 @@ static void airo_detach(dev_link_t *);
102*/ 99*/
103 100
104/* 101/*
105 The dev_info variable is the "key" that is used to match up this
106 device driver with appropriate cards, through the card configuration
107 database.
108*/
109
110static dev_info_t dev_info = "airo_cs";
111
112/*
113 A linked list of "instances" of the aironet device. Each actual 102 A linked list of "instances" of the aironet device. Each actual
114 PCMCIA card corresponds to one device instance, and is described 103 PCMCIA card corresponds to one device instance, and is described
115 by one dev_link_t structure (defined in ds.h). 104 by one dev_link_t structure (defined in ds.h).
@@ -119,15 +108,7 @@ static dev_info_t dev_info = "airo_cs";
119 device numbers are used to derive the corresponding array index. 108 device numbers are used to derive the corresponding array index.
120*/ 109*/
121 110
122static dev_link_t *dev_list = NULL;
123
124/* 111/*
125 A dev_link_t structure has fields for most things that are needed
126 to keep track of a socket, but there will usually be some device
127 specific information that also needs to be kept track of. The
128 'priv' pointer in a dev_link_t structure can be used to point to
129 a device-specific private data structure, like this.
130
131 A driver needs to provide a dev_node_t structure for each device 112 A driver needs to provide a dev_node_t structure for each device
132 on a card. In some cases, there is only one device per card (for 113 on a card. In some cases, there is only one device per card (for
133 example, ethernet cards, modems). In other cases, there may be 114 example, ethernet cards, modems). In other cases, there may be
@@ -160,20 +141,18 @@ typedef struct local_info_t {
160 141
161 ======================================================================*/ 142 ======================================================================*/
162 143
163static dev_link_t *airo_attach(void) 144static int airo_attach(struct pcmcia_device *p_dev)
164{ 145{
165 client_reg_t client_reg;
166 dev_link_t *link; 146 dev_link_t *link;
167 local_info_t *local; 147 local_info_t *local;
168 int ret; 148
169
170 DEBUG(0, "airo_attach()\n"); 149 DEBUG(0, "airo_attach()\n");
171 150
172 /* Initialize the dev_link_t structure */ 151 /* Initialize the dev_link_t structure */
173 link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL); 152 link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
174 if (!link) { 153 if (!link) {
175 printk(KERN_ERR "airo_cs: no memory for new device\n"); 154 printk(KERN_ERR "airo_cs: no memory for new device\n");
176 return NULL; 155 return -ENOMEM;
177 } 156 }
178 157
179 /* Interrupt setup */ 158 /* Interrupt setup */
@@ -197,24 +176,17 @@ static dev_link_t *airo_attach(void)
197 if (!local) { 176 if (!local) {
198 printk(KERN_ERR "airo_cs: no memory for new device\n"); 177 printk(KERN_ERR "airo_cs: no memory for new device\n");
199 kfree (link); 178 kfree (link);
200 return NULL; 179 return -ENOMEM;
201 } 180 }
202 link->priv = local; 181 link->priv = local;
203 182
204 /* Register with Card Services */ 183 link->handle = p_dev;
205 link->next = dev_list; 184 p_dev->instance = link;
206 dev_list = link; 185
207 client_reg.dev_info = &dev_info; 186 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
208 client_reg.Version = 0x0210; 187 airo_config(link);
209 client_reg.event_callback_args.client_data = link; 188
210 ret = pcmcia_register_client(&link->handle, &client_reg); 189 return 0;
211 if (ret != 0) {
212 cs_error(link->handle, RegisterClient, ret);
213 airo_detach(link);
214 return NULL;
215 }
216
217 return link;
218} /* airo_attach */ 190} /* airo_attach */
219 191
220/*====================================================================== 192/*======================================================================
@@ -226,37 +198,22 @@ static dev_link_t *airo_attach(void)
226 198
227 ======================================================================*/ 199 ======================================================================*/
228 200
229static void airo_detach(dev_link_t *link) 201static void airo_detach(struct pcmcia_device *p_dev)
230{ 202{
231 dev_link_t **linkp; 203 dev_link_t *link = dev_to_instance(p_dev);
232 204
233 DEBUG(0, "airo_detach(0x%p)\n", link); 205 DEBUG(0, "airo_detach(0x%p)\n", link);
234 206
235 /* Locate device structure */
236 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
237 if (*linkp == link) break;
238 if (*linkp == NULL)
239 return;
240
241 if (link->state & DEV_CONFIG) 207 if (link->state & DEV_CONFIG)
242 airo_release(link); 208 airo_release(link);
243 209
244 if ( ((local_info_t*)link->priv)->eth_dev ) { 210 if ( ((local_info_t*)link->priv)->eth_dev ) {
245 stop_airo_card( ((local_info_t*)link->priv)->eth_dev, 0 ); 211 stop_airo_card( ((local_info_t*)link->priv)->eth_dev, 0 );
246 } 212 }
247 ((local_info_t*)link->priv)->eth_dev = NULL; 213 ((local_info_t*)link->priv)->eth_dev = NULL;
248 214
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 */
256 *linkp = link->next;
257 kfree(link->priv); 215 kfree(link->priv);
258 kfree(link); 216 kfree(link);
259
260} /* airo_detach */ 217} /* airo_detach */
261 218
262/*====================================================================== 219/*======================================================================
@@ -492,60 +449,34 @@ static void airo_release(dev_link_t *link)
492 link->state &= ~DEV_CONFIG; 449 link->state &= ~DEV_CONFIG;
493} 450}
494 451
495/*====================================================================== 452static int airo_suspend(struct pcmcia_device *p_dev)
496 453{
497 The card status event handler. Mostly, this schedules other 454 dev_link_t *link = dev_to_instance(p_dev);
498 stuff to run after an event is received. 455 local_info_t *local = link->priv;
499 456
500 When a CARD_REMOVAL event is received, we immediately set a 457 link->state |= DEV_SUSPEND;
501 private flag to block future accesses to this device. All the 458 if (link->state & DEV_CONFIG) {
502 functions that actually access the device should check this flag 459 netif_device_detach(local->eth_dev);
503 to make sure the card is still present. 460 pcmcia_release_configuration(link->handle);
504 461 }
505 ======================================================================*/ 462
463 return 0;
464}
506 465
507static int airo_event(event_t event, int priority, 466static int airo_resume(struct pcmcia_device *p_dev)
508 event_callback_args_t *args)
509{ 467{
510 dev_link_t *link = args->client_data; 468 dev_link_t *link = dev_to_instance(p_dev);
511 local_info_t *local = link->priv; 469 local_info_t *local = link->priv;
512 470
513 DEBUG(1, "airo_event(0x%06x)\n", event); 471 link->state &= ~DEV_SUSPEND;
514 472 if (link->state & DEV_CONFIG) {
515 switch (event) { 473 pcmcia_request_configuration(link->handle, &link->conf);
516 case CS_EVENT_CARD_REMOVAL: 474 reset_airo_card(local->eth_dev);
517 link->state &= ~DEV_PRESENT; 475 netif_device_attach(local->eth_dev);
518 if (link->state & DEV_CONFIG) {
519 netif_device_detach(local->eth_dev);
520 airo_release(link);
521 }
522 break;
523 case CS_EVENT_CARD_INSERTION:
524 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
525 airo_config(link);
526 break;
527 case CS_EVENT_PM_SUSPEND:
528 link->state |= DEV_SUSPEND;
529 /* Fall through... */
530 case CS_EVENT_RESET_PHYSICAL:
531 if (link->state & DEV_CONFIG) {
532 netif_device_detach(local->eth_dev);
533 pcmcia_release_configuration(link->handle);
534 }
535 break;
536 case CS_EVENT_PM_RESUME:
537 link->state &= ~DEV_SUSPEND;
538 /* Fall through... */
539 case CS_EVENT_CARD_RESET:
540 if (link->state & DEV_CONFIG) {
541 pcmcia_request_configuration(link->handle, &link->conf);
542 reset_airo_card(local->eth_dev);
543 netif_device_attach(local->eth_dev);
544 }
545 break;
546 } 476 }
477
547 return 0; 478 return 0;
548} /* airo_event */ 479}
549 480
550static struct pcmcia_device_id airo_ids[] = { 481static struct pcmcia_device_id airo_ids[] = {
551 PCMCIA_DEVICE_MANF_CARD(0x015f, 0x000a), 482 PCMCIA_DEVICE_MANF_CARD(0x015f, 0x000a),
@@ -561,10 +492,11 @@ static struct pcmcia_driver airo_driver = {
561 .drv = { 492 .drv = {
562 .name = "airo_cs", 493 .name = "airo_cs",
563 }, 494 },
564 .attach = airo_attach, 495 .probe = airo_attach,
565 .event = airo_event, 496 .remove = airo_detach,
566 .detach = airo_detach,
567 .id_table = airo_ids, 497 .id_table = airo_ids,
498 .suspend = airo_suspend,
499 .resume = airo_resume,
568}; 500};
569 501
570static int airo_cs_init(void) 502static int airo_cs_init(void)
@@ -575,7 +507,6 @@ static int airo_cs_init(void)
575static void airo_cs_cleanup(void) 507static void airo_cs_cleanup(void)
576{ 508{
577 pcmcia_unregister_driver(&airo_driver); 509 pcmcia_unregister_driver(&airo_driver);
578 BUG_ON(dev_list != NULL);
579} 510}
580 511
581/* 512/*
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
index 17d1fd90f832..d6f4a5a3e55a 100644
--- a/drivers/net/wireless/atmel_cs.c
+++ b/drivers/net/wireless/atmel_cs.c
@@ -93,8 +93,6 @@ MODULE_SUPPORTED_DEVICE("Atmel at76c50x PCMCIA cards");
93 93
94static void atmel_config(dev_link_t *link); 94static void atmel_config(dev_link_t *link);
95static void atmel_release(dev_link_t *link); 95static void atmel_release(dev_link_t *link);
96static int atmel_event(event_t event, int priority,
97 event_callback_args_t *args);
98 96
99/* 97/*
100 The attach() and detach() entry points are used to create and destroy 98 The attach() and detach() entry points are used to create and destroy
@@ -102,8 +100,7 @@ static int atmel_event(event_t event, int priority,
102 needed to manage one actual PCMCIA card. 100 needed to manage one actual PCMCIA card.
103*/ 101*/
104 102
105static dev_link_t *atmel_attach(void); 103static void atmel_detach(struct pcmcia_device *p_dev);
106static void atmel_detach(dev_link_t *);
107 104
108/* 105/*
109 You'll also need to prototype all the functions that will actually 106 You'll also need to prototype all the functions that will actually
@@ -113,14 +110,6 @@ static void atmel_detach(dev_link_t *);
113*/ 110*/
114 111
115/* 112/*
116 The dev_info variable is the "key" that is used to match up this
117 device driver with appropriate cards, through the card configuration
118 database.
119*/
120
121static dev_info_t dev_info = "atmel_cs";
122
123/*
124 A linked list of "instances" of the atmelnet device. Each actual 113 A linked list of "instances" of the atmelnet device. Each actual
125 PCMCIA card corresponds to one device instance, and is described 114 PCMCIA card corresponds to one device instance, and is described
126 by one dev_link_t structure (defined in ds.h). 115 by one dev_link_t structure (defined in ds.h).
@@ -130,15 +119,7 @@ static dev_info_t dev_info = "atmel_cs";
130 device numbers are used to derive the corresponding array index. 119 device numbers are used to derive the corresponding array index.
131*/ 120*/
132 121
133static dev_link_t *dev_list = NULL;
134
135/* 122/*
136 A dev_link_t structure has fields for most things that are needed
137 to keep track of a socket, but there will usually be some device
138 specific information that also needs to be kept track of. The
139 'priv' pointer in a dev_link_t structure can be used to point to
140 a device-specific private data structure, like this.
141
142 A driver needs to provide a dev_node_t structure for each device 123 A driver needs to provide a dev_node_t structure for each device
143 on a card. In some cases, there is only one device per card (for 124 on a card. In some cases, there is only one device per card (for
144 example, ethernet cards, modems). In other cases, there may be 125 example, ethernet cards, modems). In other cases, there may be
@@ -171,27 +152,25 @@ typedef struct local_info_t {
171 152
172 ======================================================================*/ 153 ======================================================================*/
173 154
174static dev_link_t *atmel_attach(void) 155static int atmel_attach(struct pcmcia_device *p_dev)
175{ 156{
176 client_reg_t client_reg;
177 dev_link_t *link; 157 dev_link_t *link;
178 local_info_t *local; 158 local_info_t *local;
179 int ret; 159
180
181 DEBUG(0, "atmel_attach()\n"); 160 DEBUG(0, "atmel_attach()\n");
182 161
183 /* Initialize the dev_link_t structure */ 162 /* Initialize the dev_link_t structure */
184 link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL); 163 link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
185 if (!link) { 164 if (!link) {
186 printk(KERN_ERR "atmel_cs: no memory for new device\n"); 165 printk(KERN_ERR "atmel_cs: no memory for new device\n");
187 return NULL; 166 return -ENOMEM;
188 } 167 }
189 168
190 /* Interrupt setup */ 169 /* Interrupt setup */
191 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; 170 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
192 link->irq.IRQInfo1 = IRQ_LEVEL_ID; 171 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
193 link->irq.Handler = NULL; 172 link->irq.Handler = NULL;
194 173
195 /* 174 /*
196 General socket configuration defaults can go here. In this 175 General socket configuration defaults can go here. In this
197 client, we assume very little, and rely on the CIS for almost 176 client, we assume very little, and rely on the CIS for almost
@@ -202,30 +181,23 @@ static dev_link_t *atmel_attach(void)
202 link->conf.Attributes = 0; 181 link->conf.Attributes = 0;
203 link->conf.Vcc = 50; 182 link->conf.Vcc = 50;
204 link->conf.IntType = INT_MEMORY_AND_IO; 183 link->conf.IntType = INT_MEMORY_AND_IO;
205 184
206 /* Allocate space for private device-specific data */ 185 /* Allocate space for private device-specific data */
207 local = kzalloc(sizeof(local_info_t), GFP_KERNEL); 186 local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
208 if (!local) { 187 if (!local) {
209 printk(KERN_ERR "atmel_cs: no memory for new device\n"); 188 printk(KERN_ERR "atmel_cs: no memory for new device\n");
210 kfree (link); 189 kfree (link);
211 return NULL; 190 return -ENOMEM;
212 } 191 }
213 link->priv = local; 192 link->priv = local;
214 193
215 /* Register with Card Services */ 194 link->handle = p_dev;
216 link->next = dev_list; 195 p_dev->instance = link;
217 dev_list = link; 196
218 client_reg.dev_info = &dev_info; 197 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
219 client_reg.Version = 0x0210; 198 atmel_config(link);
220 client_reg.event_callback_args.client_data = link; 199
221 ret = pcmcia_register_client(&link->handle, &client_reg); 200 return 0;
222 if (ret != 0) {
223 cs_error(link->handle, RegisterClient, ret);
224 atmel_detach(link);
225 return NULL;
226 }
227
228 return link;
229} /* atmel_attach */ 201} /* atmel_attach */
230 202
231/*====================================================================== 203/*======================================================================
@@ -237,27 +209,15 @@ static dev_link_t *atmel_attach(void)
237 209
238 ======================================================================*/ 210 ======================================================================*/
239 211
240static void atmel_detach(dev_link_t *link) 212static void atmel_detach(struct pcmcia_device *p_dev)
241{ 213{
242 dev_link_t **linkp; 214 dev_link_t *link = dev_to_instance(p_dev);
243 215
244 DEBUG(0, "atmel_detach(0x%p)\n", link); 216 DEBUG(0, "atmel_detach(0x%p)\n", link);
245
246 /* Locate device structure */
247 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
248 if (*linkp == link) break;
249 if (*linkp == NULL)
250 return;
251 217
252 if (link->state & DEV_CONFIG) 218 if (link->state & DEV_CONFIG)
253 atmel_release(link); 219 atmel_release(link);
254
255 /* Break the link with Card Services */
256 if (link->handle)
257 pcmcia_deregister_client(link->handle);
258 220
259 /* Unlink device structure, free pieces */
260 *linkp = link->next;
261 kfree(link->priv); 221 kfree(link->priv);
262 kfree(link); 222 kfree(link);
263} 223}
@@ -477,60 +437,34 @@ static void atmel_release(dev_link_t *link)
477 link->state &= ~DEV_CONFIG; 437 link->state &= ~DEV_CONFIG;
478} 438}
479 439
480/*====================================================================== 440static int atmel_suspend(struct pcmcia_device *dev)
481 441{
482 The card status event handler. Mostly, this schedules other 442 dev_link_t *link = dev_to_instance(dev);
483 stuff to run after an event is received. 443 local_info_t *local = link->priv;
484 444
485 When a CARD_REMOVAL event is received, we immediately set a 445 link->state |= DEV_SUSPEND;
486 private flag to block future accesses to this device. All the 446 if (link->state & DEV_CONFIG) {
487 functions that actually access the device should check this flag 447 netif_device_detach(local->eth_dev);
488 to make sure the card is still present. 448 pcmcia_release_configuration(link->handle);
489 449 }
490 ======================================================================*/ 450
451 return 0;
452}
491 453
492static int atmel_event(event_t event, int priority, 454static int atmel_resume(struct pcmcia_device *dev)
493 event_callback_args_t *args)
494{ 455{
495 dev_link_t *link = args->client_data; 456 dev_link_t *link = dev_to_instance(dev);
496 local_info_t *local = link->priv; 457 local_info_t *local = link->priv;
497 458
498 DEBUG(1, "atmel_event(0x%06x)\n", event); 459 link->state &= ~DEV_SUSPEND;
499 460 if (link->state & DEV_CONFIG) {
500 switch (event) { 461 pcmcia_request_configuration(link->handle, &link->conf);
501 case CS_EVENT_CARD_REMOVAL: 462 atmel_open(local->eth_dev);
502 link->state &= ~DEV_PRESENT; 463 netif_device_attach(local->eth_dev);
503 if (link->state & DEV_CONFIG) {
504 netif_device_detach(local->eth_dev);
505 atmel_release(link);
506 }
507 break;
508 case CS_EVENT_CARD_INSERTION:
509 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
510 atmel_config(link);
511 break;
512 case CS_EVENT_PM_SUSPEND:
513 link->state |= DEV_SUSPEND;
514 /* Fall through... */
515 case CS_EVENT_RESET_PHYSICAL:
516 if (link->state & DEV_CONFIG) {
517 netif_device_detach(local->eth_dev);
518 pcmcia_release_configuration(link->handle);
519 }
520 break;
521 case CS_EVENT_PM_RESUME:
522 link->state &= ~DEV_SUSPEND;
523 /* Fall through... */
524 case CS_EVENT_CARD_RESET:
525 if (link->state & DEV_CONFIG) {
526 pcmcia_request_configuration(link->handle, &link->conf);
527 atmel_open(local->eth_dev);
528 netif_device_attach(local->eth_dev);
529 }
530 break;
531 } 464 }
465
532 return 0; 466 return 0;
533} /* atmel_event */ 467}
534 468
535/*====================================================================*/ 469/*====================================================================*/
536/* We use the driver_info field to store the correct firmware type for a card. */ 470/* We use the driver_info field to store the correct firmware type for a card. */
@@ -581,10 +515,11 @@ static struct pcmcia_driver atmel_driver = {
581 .drv = { 515 .drv = {
582 .name = "atmel_cs", 516 .name = "atmel_cs",
583 }, 517 },
584 .attach = atmel_attach, 518 .probe = atmel_attach,
585 .event = atmel_event, 519 .remove = atmel_detach,
586 .detach = atmel_detach,
587 .id_table = atmel_ids, 520 .id_table = atmel_ids,
521 .suspend = atmel_suspend,
522 .resume = atmel_resume,
588}; 523};
589 524
590static int atmel_cs_init(void) 525static int atmel_cs_init(void)
@@ -595,7 +530,6 @@ static int atmel_cs_init(void)
595static void atmel_cs_cleanup(void) 530static void atmel_cs_cleanup(void)
596{ 531{
597 pcmcia_unregister_driver(&atmel_driver); 532 pcmcia_unregister_driver(&atmel_driver);
598 BUG_ON(dev_list != NULL);
599} 533}
600 534
601/* 535/*
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index 2643976a6677..8bc0b528548f 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -25,7 +25,6 @@
25 25
26static char *version = PRISM2_VERSION " (Jouni Malinen <jkmaline@cc.hut.fi>)"; 26static char *version = PRISM2_VERSION " (Jouni Malinen <jkmaline@cc.hut.fi>)";
27static dev_info_t dev_info = "hostap_cs"; 27static dev_info_t dev_info = "hostap_cs";
28static dev_link_t *dev_list = NULL;
29 28
30MODULE_AUTHOR("Jouni Malinen"); 29MODULE_AUTHOR("Jouni Malinen");
31MODULE_DESCRIPTION("Support for Intersil Prism2-based 802.11 wireless LAN " 30MODULE_DESCRIPTION("Support for Intersil Prism2-based 802.11 wireless LAN "
@@ -203,10 +202,9 @@ static int hfa384x_to_bap(struct net_device *dev, u16 bap, void *buf, int len)
203 202
204 203
205 204
206static void prism2_detach(dev_link_t *link); 205static void prism2_detach(struct pcmcia_device *p_dev);
207static void prism2_release(u_long arg); 206static void prism2_release(u_long arg);
208static int prism2_event(event_t event, int priority, 207static int prism2_config(dev_link_t *link);
209 event_callback_args_t *args);
210 208
211 209
212static int prism2_pccard_card_present(local_info_t *local) 210static int prism2_pccard_card_present(local_info_t *local)
@@ -503,15 +501,13 @@ static struct prism2_helper_functions prism2_pccard_funcs =
503 501
504/* allocate local data and register with CardServices 502/* allocate local data and register with CardServices
505 * initialize dev_link structure, but do not configure the card yet */ 503 * initialize dev_link structure, but do not configure the card yet */
506static dev_link_t *prism2_attach(void) 504static int prism2_attach(struct pcmcia_device *p_dev)
507{ 505{
508 dev_link_t *link; 506 dev_link_t *link;
509 client_reg_t client_reg;
510 int ret;
511 507
512 link = kmalloc(sizeof(dev_link_t), GFP_KERNEL); 508 link = kmalloc(sizeof(dev_link_t), GFP_KERNEL);
513 if (link == NULL) 509 if (link == NULL)
514 return NULL; 510 return -ENOMEM;
515 511
516 memset(link, 0, sizeof(dev_link_t)); 512 memset(link, 0, sizeof(dev_link_t));
517 513
@@ -519,50 +515,27 @@ static dev_link_t *prism2_attach(void)
519 link->conf.Vcc = 33; 515 link->conf.Vcc = 33;
520 link->conf.IntType = INT_MEMORY_AND_IO; 516 link->conf.IntType = INT_MEMORY_AND_IO;
521 517
522 /* register with CardServices */ 518 link->handle = p_dev;
523 link->next = dev_list; 519 p_dev->instance = link;
524 dev_list = link; 520
525 client_reg.dev_info = &dev_info; 521 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
526 client_reg.Version = 0x0210; 522 if (prism2_config(link))
527 client_reg.event_callback_args.client_data = link; 523 PDEBUG(DEBUG_EXTRA, "prism2_config() failed\n");
528 ret = pcmcia_register_client(&link->handle, &client_reg); 524
529 if (ret != CS_SUCCESS) { 525 return 0;
530 cs_error(link->handle, RegisterClient, ret);
531 prism2_detach(link);
532 return NULL;
533 }
534 return link;
535} 526}
536 527
537 528
538static void prism2_detach(dev_link_t *link) 529static void prism2_detach(struct pcmcia_device *p_dev)
539{ 530{
540 dev_link_t **linkp; 531 dev_link_t *link = dev_to_instance(p_dev);
541 532
542 PDEBUG(DEBUG_FLOW, "prism2_detach\n"); 533 PDEBUG(DEBUG_FLOW, "prism2_detach\n");
543 534
544 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
545 if (*linkp == link)
546 break;
547 if (*linkp == NULL) {
548 printk(KERN_WARNING "%s: Attempt to detach non-existing "
549 "PCMCIA client\n", dev_info);
550 return;
551 }
552
553 if (link->state & DEV_CONFIG) { 535 if (link->state & DEV_CONFIG) {
554 prism2_release((u_long)link); 536 prism2_release((u_long)link);
555 } 537 }
556 538
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;
566 /* release net devices */ 539 /* release net devices */
567 if (link->priv) { 540 if (link->priv) {
568 struct hostap_cs_priv *hw_priv; 541 struct hostap_cs_priv *hw_priv;
@@ -846,84 +819,58 @@ static void prism2_release(u_long arg)
846 PDEBUG(DEBUG_FLOW, "release - done\n"); 819 PDEBUG(DEBUG_FLOW, "release - done\n");
847} 820}
848 821
849 822static int hostap_cs_suspend(struct pcmcia_device *p_dev)
850static int prism2_event(event_t event, int priority,
851 event_callback_args_t *args)
852{ 823{
853 dev_link_t *link = args->client_data; 824 dev_link_t *link = dev_to_instance(p_dev);
854 struct net_device *dev = (struct net_device *) link->priv; 825 struct net_device *dev = (struct net_device *) link->priv;
855 int dev_open = 0; 826 int dev_open = 0;
856 827
828 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_SUSPEND\n", dev_info);
829
830 link->state |= DEV_SUSPEND;
831
857 if (link->state & DEV_CONFIG) { 832 if (link->state & DEV_CONFIG) {
858 struct hostap_interface *iface = netdev_priv(dev); 833 struct hostap_interface *iface = netdev_priv(dev);
859 if (iface && iface->local) 834 if (iface && iface->local)
860 dev_open = iface->local->num_dev_open > 0; 835 dev_open = iface->local->num_dev_open > 0;
861 } 836 if (dev_open) {
862
863 switch (event) {
864 case CS_EVENT_CARD_INSERTION:
865 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_INSERTION\n", dev_info);
866 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
867 if (prism2_config(link)) {
868 PDEBUG(DEBUG_EXTRA, "prism2_config() failed\n");
869 }
870 break;
871
872 case CS_EVENT_CARD_REMOVAL:
873 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_REMOVAL\n", dev_info);
874 link->state &= ~DEV_PRESENT;
875 if (link->state & DEV_CONFIG) {
876 netif_stop_queue(dev); 837 netif_stop_queue(dev);
877 netif_device_detach(dev); 838 netif_device_detach(dev);
878 prism2_release((u_long) link);
879 } 839 }
880 break; 840 prism2_suspend(dev);
841 pcmcia_release_configuration(link->handle);
842 }
881 843
882 case CS_EVENT_PM_SUSPEND: 844 return 0;
883 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_SUSPEND\n", dev_info); 845}
884 link->state |= DEV_SUSPEND;
885 /* fall through */
886
887 case CS_EVENT_RESET_PHYSICAL:
888 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_RESET_PHYSICAL\n", dev_info);
889 if (link->state & DEV_CONFIG) {
890 if (dev_open) {
891 netif_stop_queue(dev);
892 netif_device_detach(dev);
893 }
894 prism2_suspend(dev);
895 pcmcia_release_configuration(link->handle);
896 }
897 break;
898 846
899 case CS_EVENT_PM_RESUME: 847static int hostap_cs_resume(struct pcmcia_device *p_dev)
900 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_RESUME\n", dev_info); 848{
901 link->state &= ~DEV_SUSPEND; 849 dev_link_t *link = dev_to_instance(p_dev);
902 /* fall through */ 850 struct net_device *dev = (struct net_device *) link->priv;
903 851 int dev_open = 0;
904 case CS_EVENT_CARD_RESET:
905 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_RESET\n", dev_info);
906 if (link->state & DEV_CONFIG) {
907 pcmcia_request_configuration(link->handle,
908 &link->conf);
909 prism2_hw_shutdown(dev, 1);
910 prism2_hw_config(dev, dev_open ? 0 : 1);
911 if (dev_open) {
912 netif_device_attach(dev);
913 netif_start_queue(dev);
914 }
915 }
916 break;
917 852
918 default: 853 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_RESUME\n", dev_info);
919 PDEBUG(DEBUG_EXTRA, "%s: prism2_event() - unknown event %d\n", 854
920 dev_info, event); 855 link->state &= ~DEV_SUSPEND;
921 break; 856 if (link->state & DEV_CONFIG) {
857 struct hostap_interface *iface = netdev_priv(dev);
858 if (iface && iface->local)
859 dev_open = iface->local->num_dev_open > 0;
860
861 pcmcia_request_configuration(link->handle, &link->conf);
862
863 prism2_hw_shutdown(dev, 1);
864 prism2_hw_config(dev, dev_open ? 0 : 1);
865 if (dev_open) {
866 netif_device_attach(dev);
867 netif_start_queue(dev);
868 }
922 } 869 }
870
923 return 0; 871 return 0;
924} 872}
925 873
926
927static struct pcmcia_device_id hostap_cs_ids[] = { 874static struct pcmcia_device_id hostap_cs_ids[] = {
928 PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7100), 875 PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7100),
929 PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300), 876 PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300),
@@ -982,11 +929,12 @@ static struct pcmcia_driver hostap_driver = {
982 .drv = { 929 .drv = {
983 .name = "hostap_cs", 930 .name = "hostap_cs",
984 }, 931 },
985 .attach = prism2_attach, 932 .probe = prism2_attach,
986 .detach = prism2_detach, 933 .remove = prism2_detach,
987 .owner = THIS_MODULE, 934 .owner = THIS_MODULE,
988 .event = prism2_event,
989 .id_table = hostap_cs_ids, 935 .id_table = hostap_cs_ids,
936 .suspend = hostap_cs_suspend,
937 .resume = hostap_cs_resume,
990}; 938};
991 939
992static int __init init_prism2_pccard(void) 940static int __init init_prism2_pccard(void)
diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c
index 92793b958e32..bf6271ee387a 100644
--- a/drivers/net/wireless/netwave_cs.c
+++ b/drivers/net/wireless/netwave_cs.c
@@ -166,8 +166,6 @@ static char *version =
166#define DEBUG(n, args...) 166#define DEBUG(n, args...)
167#endif 167#endif
168 168
169static dev_info_t dev_info = "netwave_cs";
170
171/*====================================================================*/ 169/*====================================================================*/
172 170
173/* Parameters that can be set with 'insmod' */ 171/* Parameters that can be set with 'insmod' */
@@ -195,12 +193,9 @@ module_param(mem_speed, int, 0);
195 193
196/* PCMCIA (Card Services) related functions */ 194/* PCMCIA (Card Services) related functions */
197static void netwave_release(dev_link_t *link); /* Card removal */ 195static void netwave_release(dev_link_t *link); /* Card removal */
198static int netwave_event(event_t event, int priority,
199 event_callback_args_t *args);
200static void netwave_pcmcia_config(dev_link_t *arg); /* Runs after card 196static void netwave_pcmcia_config(dev_link_t *arg); /* Runs after card
201 insertion */ 197 insertion */
202static dev_link_t *netwave_attach(void); /* Create instance */ 198static void netwave_detach(struct pcmcia_device *p_dev); /* Destroy instance */
203static void netwave_detach(dev_link_t *); /* Destroy instance */
204 199
205/* Hardware configuration */ 200/* Hardware configuration */
206static void netwave_doreset(kio_addr_t iobase, u_char __iomem *ramBase); 201static void netwave_doreset(kio_addr_t iobase, u_char __iomem *ramBase);
@@ -228,17 +223,6 @@ static struct iw_statistics* netwave_get_wireless_stats(struct net_device *dev);
228static void set_multicast_list(struct net_device *dev); 223static void set_multicast_list(struct net_device *dev);
229 224
230/* 225/*
231 A linked list of "instances" of the skeleton device. Each actual
232 PCMCIA card corresponds to one device instance, and is described
233 by one dev_link_t structure (defined in ds.h).
234
235 You may not want to use a linked list for this -- for example, the
236 memory card driver uses an array of dev_link_t pointers, where minor
237 device numbers are used to derive the corresponding array index.
238*/
239static dev_link_t *dev_list;
240
241/*
242 A dev_link_t structure has fields for most things that are needed 226 A dev_link_t structure has fields for most things that are needed
243 to keep track of a socket, but there will usually be some device 227 to keep track of a socket, but there will usually be some device
244 specific information that also needs to be kept track of. The 228 specific information that also needs to be kept track of. The
@@ -394,20 +378,18 @@ static struct iw_statistics *netwave_get_wireless_stats(struct net_device *dev)
394 * configure the card at this point -- we wait until we receive a 378 * configure the card at this point -- we wait until we receive a
395 * card insertion event. 379 * card insertion event.
396 */ 380 */
397static dev_link_t *netwave_attach(void) 381static int netwave_attach(struct pcmcia_device *p_dev)
398{ 382{
399 client_reg_t client_reg;
400 dev_link_t *link; 383 dev_link_t *link;
401 struct net_device *dev; 384 struct net_device *dev;
402 netwave_private *priv; 385 netwave_private *priv;
403 int ret; 386
404
405 DEBUG(0, "netwave_attach()\n"); 387 DEBUG(0, "netwave_attach()\n");
406 388
407 /* Initialize the dev_link_t structure */ 389 /* Initialize the dev_link_t structure */
408 dev = alloc_etherdev(sizeof(netwave_private)); 390 dev = alloc_etherdev(sizeof(netwave_private));
409 if (!dev) 391 if (!dev)
410 return NULL; 392 return -ENOMEM;
411 priv = netdev_priv(dev); 393 priv = netdev_priv(dev);
412 link = &priv->link; 394 link = &priv->link;
413 link->priv = dev; 395 link->priv = dev;
@@ -449,21 +431,14 @@ static dev_link_t *netwave_attach(void)
449 dev->open = &netwave_open; 431 dev->open = &netwave_open;
450 dev->stop = &netwave_close; 432 dev->stop = &netwave_close;
451 link->irq.Instance = dev; 433 link->irq.Instance = dev;
452
453 /* Register with Card Services */
454 link->next = dev_list;
455 dev_list = link;
456 client_reg.dev_info = &dev_info;
457 client_reg.Version = 0x0210;
458 client_reg.event_callback_args.client_data = link;
459 ret = pcmcia_register_client(&link->handle, &client_reg);
460 if (ret != 0) {
461 cs_error(link->handle, RegisterClient, ret);
462 netwave_detach(link);
463 return NULL;
464 }
465 434
466 return link; 435 link->handle = p_dev;
436 p_dev->instance = link;
437
438 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
439 netwave_pcmcia_config( link);
440
441 return 0;
467} /* netwave_attach */ 442} /* netwave_attach */
468 443
469/* 444/*
@@ -474,42 +449,20 @@ static dev_link_t *netwave_attach(void)
474 * structures are freed. Otherwise, the structures will be freed 449 * structures are freed. Otherwise, the structures will be freed
475 * when the device is released. 450 * when the device is released.
476 */ 451 */
477static void netwave_detach(dev_link_t *link) 452static void netwave_detach(struct pcmcia_device *p_dev)
478{ 453{
479 struct net_device *dev = link->priv; 454 dev_link_t *link = dev_to_instance(p_dev);
480 dev_link_t **linkp; 455 struct net_device *dev = link->priv;
481 456
482 DEBUG(0, "netwave_detach(0x%p)\n", link); 457 DEBUG(0, "netwave_detach(0x%p)\n", link);
483 458
484 /* 459 if (link->state & DEV_CONFIG)
485 If the device is currently configured and active, we won't 460 netwave_release(link);
486 actually delete it yet. Instead, it is marked so that when 461
487 the release() function is called, that will trigger a proper 462 if (link->dev)
488 detach(). 463 unregister_netdev(dev);
489 */ 464
490 if (link->state & DEV_CONFIG) 465 free_netdev(dev);
491 netwave_release(link);
492
493 /* Break the link with Card Services */
494 if (link->handle)
495 pcmcia_deregister_client(link->handle);
496
497 /* Locate device structure */
498 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
499 if (*linkp == link) break;
500 if (*linkp == NULL)
501 {
502 DEBUG(1, "netwave_cs: detach fail, '%s' not in list\n",
503 link->dev->dev_name);
504 return;
505 }
506
507 /* Unlink device structure, free pieces */
508 *linkp = link->next;
509 if (link->dev)
510 unregister_netdev(dev);
511 free_netdev(dev);
512
513} /* netwave_detach */ 466} /* netwave_detach */
514 467
515/* 468/*
@@ -935,69 +888,38 @@ static void netwave_release(dev_link_t *link)
935 link->state &= ~DEV_CONFIG; 888 link->state &= ~DEV_CONFIG;
936} 889}
937 890
938/* 891static int netwave_suspend(struct pcmcia_device *p_dev)
939 * Function netwave_event (event, priority, args)
940 *
941 * The card status event handler. Mostly, this schedules other
942 * stuff to run after an event is received. A CARD_REMOVAL event
943 * also sets some flags to discourage the net drivers from trying
944 * to talk to the card any more.
945 *
946 * When a CARD_REMOVAL event is received, we immediately set a flag
947 * to block future accesses to this device. All the functions that
948 * actually access the device should check this flag to make sure
949 * the card is still present.
950 *
951 */
952static int netwave_event(event_t event, int priority,
953 event_callback_args_t *args)
954{ 892{
955 dev_link_t *link = args->client_data; 893 dev_link_t *link = dev_to_instance(p_dev);
956 struct net_device *dev = link->priv; 894 struct net_device *dev = link->priv;
957 895
958 DEBUG(1, "netwave_event(0x%06x)\n", event);
959
960 switch (event) {
961 case CS_EVENT_REGISTRATION_COMPLETE:
962 DEBUG(0, "netwave_cs: registration complete\n");
963 break;
964
965 case CS_EVENT_CARD_REMOVAL:
966 link->state &= ~DEV_PRESENT;
967 if (link->state & DEV_CONFIG) {
968 netif_device_detach(dev);
969 netwave_release(link);
970 }
971 break;
972 case CS_EVENT_CARD_INSERTION:
973 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
974 netwave_pcmcia_config( link);
975 break;
976 case CS_EVENT_PM_SUSPEND:
977 link->state |= DEV_SUSPEND; 896 link->state |= DEV_SUSPEND;
978 /* Fall through... */
979 case CS_EVENT_RESET_PHYSICAL:
980 if (link->state & DEV_CONFIG) { 897 if (link->state & DEV_CONFIG) {
981 if (link->open) 898 if (link->open)
982 netif_device_detach(dev); 899 netif_device_detach(dev);
983 pcmcia_release_configuration(link->handle); 900 pcmcia_release_configuration(link->handle);
984 } 901 }
985 break; 902
986 case CS_EVENT_PM_RESUME: 903 return 0;
904}
905
906static int netwave_resume(struct pcmcia_device *p_dev)
907{
908 dev_link_t *link = dev_to_instance(p_dev);
909 struct net_device *dev = link->priv;
910
987 link->state &= ~DEV_SUSPEND; 911 link->state &= ~DEV_SUSPEND;
988 /* Fall through... */
989 case CS_EVENT_CARD_RESET:
990 if (link->state & DEV_CONFIG) { 912 if (link->state & DEV_CONFIG) {
991 pcmcia_request_configuration(link->handle, &link->conf); 913 pcmcia_request_configuration(link->handle, &link->conf);
992 if (link->open) { 914 if (link->open) {
993 netwave_reset(dev); 915 netwave_reset(dev);
994 netif_device_attach(dev); 916 netif_device_attach(dev);
995 } 917 }
996 } 918 }
997 break; 919
998 } 920 return 0;
999 return 0; 921}
1000} /* netwave_event */ 922
1001 923
1002/* 924/*
1003 * Function netwave_doreset (ioBase, ramBase) 925 * Function netwave_doreset (ioBase, ramBase)
@@ -1491,10 +1413,11 @@ static struct pcmcia_driver netwave_driver = {
1491 .drv = { 1413 .drv = {
1492 .name = "netwave_cs", 1414 .name = "netwave_cs",
1493 }, 1415 },
1494 .attach = netwave_attach, 1416 .probe = netwave_attach,
1495 .event = netwave_event, 1417 .remove = netwave_detach,
1496 .detach = netwave_detach,
1497 .id_table = netwave_ids, 1418 .id_table = netwave_ids,
1419 .suspend = netwave_suspend,
1420 .resume = netwave_resume,
1498}; 1421};
1499 1422
1500static int __init init_netwave_cs(void) 1423static int __init init_netwave_cs(void)
@@ -1505,7 +1428,6 @@ static int __init init_netwave_cs(void)
1505static void __exit exit_netwave_cs(void) 1428static void __exit exit_netwave_cs(void)
1506{ 1429{
1507 pcmcia_unregister_driver(&netwave_driver); 1430 pcmcia_unregister_driver(&netwave_driver);
1508 BUG_ON(dev_list != NULL);
1509} 1431}
1510 1432
1511module_init(init_netwave_cs); 1433module_init(init_netwave_cs);
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c
index dc1128a00971..b664708481cc 100644
--- a/drivers/net/wireless/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco_cs.c
@@ -43,17 +43,6 @@ module_param(ignore_cis_vcc, int, 0);
43MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket"); 43MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket");
44 44
45/********************************************************************/ 45/********************************************************************/
46/* Magic constants */
47/********************************************************************/
48
49/*
50 * The dev_info variable is the "key" that is used to match up this
51 * device driver with appropriate cards, through the card
52 * configuration database.
53 */
54static dev_info_t dev_info = DRIVER_NAME;
55
56/********************************************************************/
57/* Data structures */ 46/* Data structures */
58/********************************************************************/ 47/********************************************************************/
59 48
@@ -69,19 +58,14 @@ struct orinoco_pccard {
69 unsigned long hard_reset_in_progress; 58 unsigned long hard_reset_in_progress;
70}; 59};
71 60
72/*
73 * A linked list of "instances" of the device. Each actual PCMCIA
74 * card corresponds to one device instance, and is described by one
75 * dev_link_t structure (defined in ds.h).
76 */
77static dev_link_t *dev_list; /* = NULL */
78 61
79/********************************************************************/ 62/********************************************************************/
80/* Function prototypes */ 63/* Function prototypes */
81/********************************************************************/ 64/********************************************************************/
82 65
66static void orinoco_cs_config(dev_link_t *link);
83static void orinoco_cs_release(dev_link_t *link); 67static void orinoco_cs_release(dev_link_t *link);
84static void orinoco_cs_detach(dev_link_t *link); 68static void orinoco_cs_detach(struct pcmcia_device *p_dev);
85 69
86/********************************************************************/ 70/********************************************************************/
87/* Device methods */ 71/* Device methods */
@@ -119,19 +103,17 @@ orinoco_cs_hard_reset(struct orinoco_private *priv)
119 * The dev_link structure is initialized, but we don't actually 103 * The dev_link structure is initialized, but we don't actually
120 * configure the card at this point -- we wait until we receive a card 104 * configure the card at this point -- we wait until we receive a card
121 * insertion event. */ 105 * insertion event. */
122static dev_link_t * 106static int
123orinoco_cs_attach(void) 107orinoco_cs_attach(struct pcmcia_device *p_dev)
124{ 108{
125 struct net_device *dev; 109 struct net_device *dev;
126 struct orinoco_private *priv; 110 struct orinoco_private *priv;
127 struct orinoco_pccard *card; 111 struct orinoco_pccard *card;
128 dev_link_t *link; 112 dev_link_t *link;
129 client_reg_t client_reg;
130 int ret;
131 113
132 dev = alloc_orinocodev(sizeof(*card), orinoco_cs_hard_reset); 114 dev = alloc_orinocodev(sizeof(*card), orinoco_cs_hard_reset);
133 if (! dev) 115 if (! dev)
134 return NULL; 116 return -ENOMEM;
135 priv = netdev_priv(dev); 117 priv = netdev_priv(dev);
136 card = priv->card; 118 card = priv->card;
137 119
@@ -154,22 +136,15 @@ orinoco_cs_attach(void)
154 link->conf.IntType = INT_MEMORY_AND_IO; 136 link->conf.IntType = INT_MEMORY_AND_IO;
155 137
156 /* Register with Card Services */ 138 /* Register with Card Services */
157 /* FIXME: need a lock? */ 139 link->next = NULL;
158 link->next = dev_list; 140
159 dev_list = link; 141 link->handle = p_dev;
160 142 p_dev->instance = link;
161 client_reg.dev_info = &dev_info; 143
162 client_reg.Version = 0x0210; /* FIXME: what does this mean? */ 144 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
163 client_reg.event_callback_args.client_data = link; 145 orinoco_cs_config(link);
164
165 ret = pcmcia_register_client(&link->handle, &client_reg);
166 if (ret != CS_SUCCESS) {
167 cs_error(link->handle, RegisterClient, ret);
168 orinoco_cs_detach(link);
169 return NULL;
170 }
171 146
172 return link; 147 return 0;
173} /* orinoco_cs_attach */ 148} /* orinoco_cs_attach */
174 149
175/* 150/*
@@ -178,27 +153,14 @@ orinoco_cs_attach(void)
178 * are freed. Otherwise, the structures will be freed when the device 153 * are freed. Otherwise, the structures will be freed when the device
179 * is released. 154 * is released.
180 */ 155 */
181static void orinoco_cs_detach(dev_link_t *link) 156static void orinoco_cs_detach(struct pcmcia_device *p_dev)
182{ 157{
183 dev_link_t **linkp; 158 dev_link_t *link = dev_to_instance(p_dev);
184 struct net_device *dev = link->priv; 159 struct net_device *dev = link->priv;
185 160
186 /* Locate device structure */
187 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
188 if (*linkp == link)
189 break;
190
191 BUG_ON(*linkp == NULL);
192
193 if (link->state & DEV_CONFIG) 161 if (link->state & DEV_CONFIG)
194 orinoco_cs_release(link); 162 orinoco_cs_release(link);
195 163
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 */
201 *linkp = link->next;
202 DEBUG(0, PFX "detach: link=%p link->dev=%p\n", link, link->dev); 164 DEBUG(0, PFX "detach: link=%p link->dev=%p\n", link, link->dev);
203 if (link->dev) { 165 if (link->dev) {
204 DEBUG(0, PFX "About to unregister net device %p\n", 166 DEBUG(0, PFX "About to unregister net device %p\n",
@@ -465,106 +427,82 @@ orinoco_cs_release(dev_link_t *link)
465 ioport_unmap(priv->hw.iobase); 427 ioport_unmap(priv->hw.iobase);
466} /* orinoco_cs_release */ 428} /* orinoco_cs_release */
467 429
468/* 430static int orinoco_cs_suspend(struct pcmcia_device *p_dev)
469 * The card status event handler. Mostly, this schedules other stuff
470 * to run after an event is received.
471 */
472static int
473orinoco_cs_event(event_t event, int priority,
474 event_callback_args_t * args)
475{ 431{
476 dev_link_t *link = args->client_data; 432 dev_link_t *link = dev_to_instance(p_dev);
477 struct net_device *dev = link->priv; 433 struct net_device *dev = link->priv;
478 struct orinoco_private *priv = netdev_priv(dev); 434 struct orinoco_private *priv = netdev_priv(dev);
479 struct orinoco_pccard *card = priv->card; 435 struct orinoco_pccard *card = priv->card;
480 int err = 0; 436 int err = 0;
481 unsigned long flags; 437 unsigned long flags;
482 438
483 switch (event) { 439 link->state |= DEV_SUSPEND;
484 case CS_EVENT_CARD_REMOVAL: 440 if (link->state & DEV_CONFIG) {
485 link->state &= ~DEV_PRESENT; 441 /* This is probably racy, but I can't think of
486 if (link->state & DEV_CONFIG) { 442 a better way, short of rewriting the PCMCIA
487 unsigned long flags; 443 layer to not suck :-( */
488 444 if (! test_bit(0, &card->hard_reset_in_progress)) {
489 spin_lock_irqsave(&priv->lock, flags); 445 spin_lock_irqsave(&priv->lock, flags);
446
447 err = __orinoco_down(dev);
448 if (err)
449 printk(KERN_WARNING "%s: Error %d downing interface\n",
450 dev->name, err);
451
490 netif_device_detach(dev); 452 netif_device_detach(dev);
491 priv->hw_unavailable++; 453 priv->hw_unavailable++;
454
492 spin_unlock_irqrestore(&priv->lock, flags); 455 spin_unlock_irqrestore(&priv->lock, flags);
493 } 456 }
494 break;
495 457
496 case CS_EVENT_CARD_INSERTION: 458 pcmcia_release_configuration(link->handle);
497 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 459 }
498 orinoco_cs_config(link);
499 break;
500 460
501 case CS_EVENT_PM_SUSPEND: 461 return 0;
502 link->state |= DEV_SUSPEND; 462}
503 /* Fall through... */ 463
504 case CS_EVENT_RESET_PHYSICAL: 464static int orinoco_cs_resume(struct pcmcia_device *p_dev)
505 /* Mark the device as stopped, to block IO until later */ 465{
506 if (link->state & DEV_CONFIG) { 466 dev_link_t *link = dev_to_instance(p_dev);
507 /* This is probably racy, but I can't think of 467 struct net_device *dev = link->priv;
508 a better way, short of rewriting the PCMCIA 468 struct orinoco_private *priv = netdev_priv(dev);
509 layer to not suck :-( */ 469 struct orinoco_pccard *card = priv->card;
510 if (! test_bit(0, &card->hard_reset_in_progress)) { 470 int err = 0;
511 spin_lock_irqsave(&priv->lock, flags); 471 unsigned long flags;
512 472
513 err = __orinoco_down(dev); 473 link->state &= ~DEV_SUSPEND;
514 if (err) 474 if (link->state & DEV_CONFIG) {
515 printk(KERN_WARNING "%s: %s: Error %d downing interface\n", 475 /* FIXME: should we double check that this is
516 dev->name, 476 * the same card as we had before */
517 event == CS_EVENT_PM_SUSPEND ? "SUSPEND" : "RESET_PHYSICAL", 477 pcmcia_request_configuration(link->handle, &link->conf);
518 err); 478
519 479 if (! test_bit(0, &card->hard_reset_in_progress)) {
520 netif_device_detach(dev); 480 err = orinoco_reinit_firmware(dev);
521 priv->hw_unavailable++; 481 if (err) {
522 482 printk(KERN_ERR "%s: Error %d re-initializing firmware\n",
523 spin_unlock_irqrestore(&priv->lock, flags); 483 dev->name, err);
484 return -EIO;
524 } 485 }
525 486
526 pcmcia_release_configuration(link->handle); 487 spin_lock_irqsave(&priv->lock, flags);
527 } 488
528 break; 489 netif_device_attach(dev);
490 priv->hw_unavailable--;
529 491
530 case CS_EVENT_PM_RESUME: 492 if (priv->open && ! priv->hw_unavailable) {
531 link->state &= ~DEV_SUSPEND; 493 err = __orinoco_up(dev);
532 /* Fall through... */ 494 if (err)
533 case CS_EVENT_CARD_RESET: 495 printk(KERN_ERR "%s: Error %d restarting card\n",
534 if (link->state & DEV_CONFIG) {
535 /* FIXME: should we double check that this is
536 * the same card as we had before */
537 pcmcia_request_configuration(link->handle, &link->conf);
538
539 if (! test_bit(0, &card->hard_reset_in_progress)) {
540 err = orinoco_reinit_firmware(dev);
541 if (err) {
542 printk(KERN_ERR "%s: Error %d re-initializing firmware\n",
543 dev->name, err); 496 dev->name, err);
544 break;
545 }
546
547 spin_lock_irqsave(&priv->lock, flags);
548
549 netif_device_attach(dev);
550 priv->hw_unavailable--;
551
552 if (priv->open && ! priv->hw_unavailable) {
553 err = __orinoco_up(dev);
554 if (err)
555 printk(KERN_ERR "%s: Error %d restarting card\n",
556 dev->name, err);
557
558 }
559
560 spin_unlock_irqrestore(&priv->lock, flags);
561 } 497 }
498
499 spin_unlock_irqrestore(&priv->lock, flags);
562 } 500 }
563 break;
564 } 501 }
565 502
566 return err; 503 return 0;
567} /* orinoco_cs_event */ 504}
505
568 506
569/********************************************************************/ 507/********************************************************************/
570/* Module initialization */ 508/* Module initialization */
@@ -665,10 +603,11 @@ static struct pcmcia_driver orinoco_driver = {
665 .drv = { 603 .drv = {
666 .name = DRIVER_NAME, 604 .name = DRIVER_NAME,
667 }, 605 },
668 .attach = orinoco_cs_attach, 606 .probe = orinoco_cs_attach,
669 .detach = orinoco_cs_detach, 607 .remove = orinoco_cs_detach,
670 .event = orinoco_cs_event,
671 .id_table = orinoco_cs_ids, 608 .id_table = orinoco_cs_ids,
609 .suspend = orinoco_cs_suspend,
610 .resume = orinoco_cs_resume,
672}; 611};
673 612
674static int __init 613static int __init
@@ -683,7 +622,6 @@ static void __exit
683exit_orinoco_cs(void) 622exit_orinoco_cs(void)
684{ 623{
685 pcmcia_unregister_driver(&orinoco_driver); 624 pcmcia_unregister_driver(&orinoco_driver);
686 BUG_ON(dev_list != NULL);
687} 625}
688 626
689module_init(init_orinoco_cs); 627module_init(init_orinoco_cs);
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 70fd6fd8feb9..319180ca7e71 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -92,9 +92,7 @@ module_param(pc_debug, int, 0);
92/** Prototypes based on PCMCIA skeleton driver *******************************/ 92/** Prototypes based on PCMCIA skeleton driver *******************************/
93static void ray_config(dev_link_t *link); 93static 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 void ray_detach(struct pcmcia_device *p_dev);
96static dev_link_t *ray_attach(void);
97static void ray_detach(dev_link_t *);
98 96
99/***** Prototypes indicated by device structure ******************************/ 97/***** Prototypes indicated by device structure ******************************/
100static int ray_dev_close(struct net_device *dev); 98static int ray_dev_close(struct net_device *dev);
@@ -192,12 +190,6 @@ static int bc;
192static char *phy_addr = NULL; 190static char *phy_addr = NULL;
193 191
194 192
195/* The dev_info variable is the "key" that is used to match up this
196 device driver with appropriate cards, through the card configuration
197 database.
198*/
199static dev_info_t dev_info = "ray_cs";
200
201/* A linked list of "instances" of the ray device. Each actual 193/* A linked list of "instances" of the ray device. Each actual
202 PCMCIA card corresponds to one device instance, and is described 194 PCMCIA card corresponds to one device instance, and is described
203 by one dev_link_t structure (defined in ds.h). 195 by one dev_link_t structure (defined in ds.h).
@@ -314,12 +306,10 @@ static char rcsid[] = "Raylink/WebGear wireless LAN - Corey <Thomas corey@world.
314 configure the card at this point -- we wait until we receive a 306 configure the card at this point -- we wait until we receive a
315 card insertion event. 307 card insertion event.
316=============================================================================*/ 308=============================================================================*/
317static dev_link_t *ray_attach(void) 309static int ray_attach(struct pcmcia_device *p_dev)
318{ 310{
319 client_reg_t client_reg;
320 dev_link_t *link; 311 dev_link_t *link;
321 ray_dev_t *local; 312 ray_dev_t *local;
322 int ret;
323 struct net_device *dev; 313 struct net_device *dev;
324 314
325 DEBUG(1, "ray_attach()\n"); 315 DEBUG(1, "ray_attach()\n");
@@ -328,7 +318,7 @@ static dev_link_t *ray_attach(void)
328 link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); 318 link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
329 319
330 if (!link) 320 if (!link)
331 return NULL; 321 return -ENOMEM;
332 322
333 /* Allocate space for private device-specific data */ 323 /* Allocate space for private device-specific data */
334 dev = alloc_etherdev(sizeof(ray_dev_t)); 324 dev = alloc_etherdev(sizeof(ray_dev_t));
@@ -387,30 +377,19 @@ static dev_link_t *ray_attach(void)
387 dev->stop = &ray_dev_close; 377 dev->stop = &ray_dev_close;
388 netif_stop_queue(dev); 378 netif_stop_queue(dev);
389 379
390 /* Register with Card Services */ 380 init_timer(&local->timer);
391 link->next = dev_list;
392 dev_list = link;
393 client_reg.dev_info = &dev_info;
394 client_reg.Version = 0x0210;
395 client_reg.event_callback_args.client_data = link;
396 381
397 DEBUG(2,"ray_cs ray_attach calling pcmcia_register_client(...)\n"); 382 link->handle = p_dev;
383 p_dev->instance = link;
398 384
399 init_timer(&local->timer); 385 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
386 ray_config(link);
400 387
401 ret = pcmcia_register_client(&link->handle, &client_reg); 388 return 0;
402 if (ret != 0) {
403 printk("ray_cs ray_attach RegisterClient unhappy - detaching\n");
404 cs_error(link->handle, RegisterClient, ret);
405 ray_detach(link);
406 return NULL;
407 }
408 DEBUG(2,"ray_cs ray_attach ending\n");
409 return link;
410 389
411fail_alloc_dev: 390fail_alloc_dev:
412 kfree(link); 391 kfree(link);
413 return NULL; 392 return -ENOMEM;
414} /* ray_attach */ 393} /* ray_attach */
415/*============================================================================= 394/*=============================================================================
416 This deletes a driver "instance". The device is de-registered 395 This deletes a driver "instance". The device is de-registered
@@ -418,9 +397,12 @@ fail_alloc_dev:
418 structures are freed. Otherwise, the structures will be freed 397 structures are freed. Otherwise, the structures will be freed
419 when the device is released. 398 when the device is released.
420=============================================================================*/ 399=============================================================================*/
421static void ray_detach(dev_link_t *link) 400static void ray_detach(struct pcmcia_device *p_dev)
422{ 401{
402 dev_link_t *link = dev_to_instance(p_dev);
423 dev_link_t **linkp; 403 dev_link_t **linkp;
404 struct net_device *dev;
405 ray_dev_t *local;
424 406
425 DEBUG(1, "ray_detach(0x%p)\n", link); 407 DEBUG(1, "ray_detach(0x%p)\n", link);
426 408
@@ -430,22 +412,18 @@ static void ray_detach(dev_link_t *link)
430 if (*linkp == NULL) 412 if (*linkp == NULL)
431 return; 413 return;
432 414
433 /* If the device is currently configured and active, we won't 415 dev = link->priv;
434 actually delete it yet. Instead, it is marked so that when 416
435 the release() function is called, that will trigger a proper 417 if (link->state & DEV_CONFIG) {
436 detach(). 418 ray_release(link);
437 */ 419
438 if (link->state & DEV_CONFIG) 420 local = (ray_dev_t *)dev->priv;
439 ray_release(link); 421 del_timer(&local->timer);
422 }
440 423
441 /* Break the link with Card Services */
442 if (link->handle)
443 pcmcia_deregister_client(link->handle);
444
445 /* Unlink device structure, free pieces */ 424 /* Unlink device structure, free pieces */
446 *linkp = link->next; 425 *linkp = link->next;
447 if (link->priv) { 426 if (link->priv) {
448 struct net_device *dev = link->priv;
449 if (link->dev) unregister_netdev(dev); 427 if (link->dev) unregister_netdev(dev);
450 free_netdev(dev); 428 free_netdev(dev);
451 } 429 }
@@ -891,65 +869,40 @@ static void ray_release(dev_link_t *link)
891 DEBUG(2,"ray_release ending\n"); 869 DEBUG(2,"ray_release ending\n");
892} 870}
893 871
894/*============================================================================= 872static int ray_suspend(struct pcmcia_device *p_dev)
895 The card status event handler. Mostly, this schedules other
896 stuff to run after an event is received. A CARD_REMOVAL event
897 also sets some flags to discourage the net drivers from trying
898 to talk to the card any more.
899
900 When a CARD_REMOVAL event is received, we immediately set a flag
901 to block future accesses to this device. All the functions that
902 actually access the device should check this flag to make sure
903 the card is still present.
904=============================================================================*/
905static int ray_event(event_t event, int priority,
906 event_callback_args_t *args)
907{ 873{
908 dev_link_t *link = args->client_data; 874 dev_link_t *link = dev_to_instance(p_dev);
909 struct net_device *dev = link->priv; 875 struct net_device *dev = link->priv;
910 ray_dev_t *local = (ray_dev_t *)dev->priv; 876
911 DEBUG(1, "ray_event(0x%06x)\n", event); 877 link->state |= DEV_SUSPEND;
912
913 switch (event) {
914 case CS_EVENT_CARD_REMOVAL:
915 link->state &= ~DEV_PRESENT;
916 netif_device_detach(dev);
917 if (link->state & DEV_CONFIG) {
918 ray_release(link);
919 del_timer(&local->timer);
920 }
921 break;
922 case CS_EVENT_CARD_INSERTION:
923 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
924 ray_config(link);
925 break;
926 case CS_EVENT_PM_SUSPEND:
927 link->state |= DEV_SUSPEND;
928 /* Fall through... */
929 case CS_EVENT_RESET_PHYSICAL:
930 if (link->state & DEV_CONFIG) { 878 if (link->state & DEV_CONFIG) {
931 if (link->open) 879 if (link->open)
932 netif_device_detach(dev); 880 netif_device_detach(dev);
933 881
934 pcmcia_release_configuration(link->handle); 882 pcmcia_release_configuration(link->handle);
935 } 883 }
936 break; 884
937 case CS_EVENT_PM_RESUME: 885
938 link->state &= ~DEV_SUSPEND; 886 return 0;
939 /* Fall through... */ 887}
940 case CS_EVENT_CARD_RESET: 888
889static int ray_resume(struct pcmcia_device *p_dev)
890{
891 dev_link_t *link = dev_to_instance(p_dev);
892 struct net_device *dev = link->priv;
893
894 link->state &= ~DEV_SUSPEND;
941 if (link->state & DEV_CONFIG) { 895 if (link->state & DEV_CONFIG) {
942 pcmcia_request_configuration(link->handle, &link->conf); 896 pcmcia_request_configuration(link->handle, &link->conf);
943 if (link->open) { 897 if (link->open) {
944 ray_reset(dev); 898 ray_reset(dev);
945 netif_device_attach(dev); 899 netif_device_attach(dev);
946 } 900 }
947 } 901 }
948 break; 902
949 } 903 return 0;
950 return 0; 904}
951 DEBUG(2,"ray_event ending\n"); 905
952} /* ray_event */
953/*===========================================================================*/ 906/*===========================================================================*/
954int ray_dev_init(struct net_device *dev) 907int ray_dev_init(struct net_device *dev)
955{ 908{
@@ -2945,10 +2898,11 @@ static struct pcmcia_driver ray_driver = {
2945 .drv = { 2898 .drv = {
2946 .name = "ray_cs", 2899 .name = "ray_cs",
2947 }, 2900 },
2948 .attach = ray_attach, 2901 .probe = ray_attach,
2949 .event = ray_event, 2902 .remove = ray_detach,
2950 .detach = ray_detach,
2951 .id_table = ray_ids, 2903 .id_table = ray_ids,
2904 .suspend = ray_suspend,
2905 .resume = ray_resume,
2952}; 2906};
2953 2907
2954static int __init init_ray_cs(void) 2908static int __init init_ray_cs(void)
diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c
index b1bbc8e8e91f..fee4be1ce810 100644
--- a/drivers/net/wireless/spectrum_cs.c
+++ b/drivers/net/wireless/spectrum_cs.c
@@ -57,17 +57,6 @@ module_param(ignore_cis_vcc, int, 0);
57MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket"); 57MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket");
58 58
59/********************************************************************/ 59/********************************************************************/
60/* Magic constants */
61/********************************************************************/
62
63/*
64 * The dev_info variable is the "key" that is used to match up this
65 * device driver with appropriate cards, through the card
66 * configuration database.
67 */
68static dev_info_t dev_info = DRIVER_NAME;
69
70/********************************************************************/
71/* Data structures */ 60/* Data structures */
72/********************************************************************/ 61/********************************************************************/
73 62
@@ -78,19 +67,12 @@ struct orinoco_pccard {
78 dev_node_t node; 67 dev_node_t node;
79}; 68};
80 69
81/*
82 * A linked list of "instances" of the device. Each actual PCMCIA
83 * card corresponds to one device instance, and is described by one
84 * dev_link_t structure (defined in ds.h).
85 */
86static dev_link_t *dev_list; /* = NULL */
87
88/********************************************************************/ 70/********************************************************************/
89/* Function prototypes */ 71/* Function prototypes */
90/********************************************************************/ 72/********************************************************************/
91 73
74static void spectrum_cs_config(dev_link_t *link);
92static void spectrum_cs_release(dev_link_t *link); 75static void spectrum_cs_release(dev_link_t *link);
93static void spectrum_cs_detach(dev_link_t *link);
94 76
95/********************************************************************/ 77/********************************************************************/
96/* Firmware downloader */ 78/* Firmware downloader */
@@ -601,19 +583,17 @@ spectrum_cs_hard_reset(struct orinoco_private *priv)
601 * The dev_link structure is initialized, but we don't actually 583 * The dev_link structure is initialized, but we don't actually
602 * configure the card at this point -- we wait until we receive a card 584 * configure the card at this point -- we wait until we receive a card
603 * insertion event. */ 585 * insertion event. */
604static dev_link_t * 586static int
605spectrum_cs_attach(void) 587spectrum_cs_attach(struct pcmcia_device *p_dev)
606{ 588{
607 struct net_device *dev; 589 struct net_device *dev;
608 struct orinoco_private *priv; 590 struct orinoco_private *priv;
609 struct orinoco_pccard *card; 591 struct orinoco_pccard *card;
610 dev_link_t *link; 592 dev_link_t *link;
611 client_reg_t client_reg;
612 int ret;
613 593
614 dev = alloc_orinocodev(sizeof(*card), spectrum_cs_hard_reset); 594 dev = alloc_orinocodev(sizeof(*card), spectrum_cs_hard_reset);
615 if (! dev) 595 if (! dev)
616 return NULL; 596 return -ENOMEM;
617 priv = netdev_priv(dev); 597 priv = netdev_priv(dev);
618 card = priv->card; 598 card = priv->card;
619 599
@@ -635,23 +615,13 @@ spectrum_cs_attach(void)
635 link->conf.Attributes = 0; 615 link->conf.Attributes = 0;
636 link->conf.IntType = INT_MEMORY_AND_IO; 616 link->conf.IntType = INT_MEMORY_AND_IO;
637 617
638 /* Register with Card Services */ 618 link->handle = p_dev;
639 /* FIXME: need a lock? */ 619 p_dev->instance = link;
640 link->next = dev_list;
641 dev_list = link;
642 620
643 client_reg.dev_info = &dev_info; 621 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
644 client_reg.Version = 0x0210; /* FIXME: what does this mean? */ 622 spectrum_cs_config(link);
645 client_reg.event_callback_args.client_data = link;
646 623
647 ret = pcmcia_register_client(&link->handle, &client_reg); 624 return 0;
648 if (ret != CS_SUCCESS) {
649 cs_error(link->handle, RegisterClient, ret);
650 spectrum_cs_detach(link);
651 return NULL;
652 }
653
654 return link;
655} /* spectrum_cs_attach */ 625} /* spectrum_cs_attach */
656 626
657/* 627/*
@@ -660,27 +630,14 @@ spectrum_cs_attach(void)
660 * are freed. Otherwise, the structures will be freed when the device 630 * are freed. Otherwise, the structures will be freed when the device
661 * is released. 631 * is released.
662 */ 632 */
663static void spectrum_cs_detach(dev_link_t *link) 633static void spectrum_cs_detach(struct pcmcia_device *p_dev)
664{ 634{
665 dev_link_t **linkp; 635 dev_link_t *link = dev_to_instance(p_dev);
666 struct net_device *dev = link->priv; 636 struct net_device *dev = link->priv;
667 637
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) 638 if (link->state & DEV_CONFIG)
676 spectrum_cs_release(link); 639 spectrum_cs_release(link);
677 640
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); 641 DEBUG(0, PFX "detach: link=%p link->dev=%p\n", link, link->dev);
685 if (link->dev) { 642 if (link->dev) {
686 DEBUG(0, PFX "About to unregister net device %p\n", 643 DEBUG(0, PFX "About to unregister net device %p\n",
@@ -948,82 +905,56 @@ spectrum_cs_release(dev_link_t *link)
948 ioport_unmap(priv->hw.iobase); 905 ioport_unmap(priv->hw.iobase);
949} /* spectrum_cs_release */ 906} /* spectrum_cs_release */
950 907
951/* 908
952 * The card status event handler. Mostly, this schedules other stuff
953 * to run after an event is received.
954 */
955static int 909static int
956spectrum_cs_event(event_t event, int priority, 910spectrum_cs_suspend(struct pcmcia_device *p_dev)
957 event_callback_args_t * args)
958{ 911{
959 dev_link_t *link = args->client_data; 912 dev_link_t *link = dev_to_instance(p_dev);
960 struct net_device *dev = link->priv; 913 struct net_device *dev = link->priv;
961 struct orinoco_private *priv = netdev_priv(dev); 914 struct orinoco_private *priv = netdev_priv(dev);
962 int err = 0;
963 unsigned long flags; 915 unsigned long flags;
916 int err = 0;
964 917
965 switch (event) { 918 link->state |= DEV_SUSPEND;
966 case CS_EVENT_CARD_REMOVAL: 919 /* Mark the device as stopped, to block IO until later */
967 link->state &= ~DEV_PRESENT; 920 if (link->state & DEV_CONFIG) {
968 if (link->state & DEV_CONFIG) { 921 spin_lock_irqsave(&priv->lock, flags);
969 unsigned long flags;
970 922
971 spin_lock_irqsave(&priv->lock, flags); 923 err = __orinoco_down(dev);
972 netif_device_detach(dev); 924 if (err)
973 priv->hw_unavailable++; 925 printk(KERN_WARNING "%s: Error %d downing interface\n",
974 spin_unlock_irqrestore(&priv->lock, flags); 926 dev->name, err);
975 }
976 break;
977 927
978 case CS_EVENT_CARD_INSERTION: 928 netif_device_detach(dev);
979 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 929 priv->hw_unavailable++;
980 spectrum_cs_config(link);
981 break;
982 930
983 case CS_EVENT_PM_SUSPEND: 931 spin_unlock_irqrestore(&priv->lock, flags);
984 link->state |= DEV_SUSPEND;
985 /* Fall through... */
986 case CS_EVENT_RESET_PHYSICAL:
987 /* Mark the device as stopped, to block IO until later */
988 if (link->state & DEV_CONFIG) {
989 /* This is probably racy, but I can't think of
990 a better way, short of rewriting the PCMCIA
991 layer to not suck :-( */
992 spin_lock_irqsave(&priv->lock, flags);
993
994 err = __orinoco_down(dev);
995 if (err)
996 printk(KERN_WARNING "%s: %s: Error %d downing interface\n",
997 dev->name,
998 event == CS_EVENT_PM_SUSPEND ? "SUSPEND" : "RESET_PHYSICAL",
999 err);
1000
1001 netif_device_detach(dev);
1002 priv->hw_unavailable++;
1003
1004 spin_unlock_irqrestore(&priv->lock, flags);
1005
1006 pcmcia_release_configuration(link->handle);
1007 }
1008 break;
1009 932
1010 case CS_EVENT_PM_RESUME: 933 pcmcia_release_configuration(link->handle);
1011 link->state &= ~DEV_SUSPEND; 934 }
1012 /* Fall through... */ 935
1013 case CS_EVENT_CARD_RESET: 936 return 0;
1014 if (link->state & DEV_CONFIG) { 937}
1015 /* FIXME: should we double check that this is 938
1016 * the same card as we had before */ 939static int
1017 pcmcia_request_configuration(link->handle, &link->conf); 940spectrum_cs_resume(struct pcmcia_device *p_dev)
1018 netif_device_attach(dev); 941{
1019 priv->hw_unavailable--; 942 dev_link_t *link = dev_to_instance(p_dev);
1020 schedule_work(&priv->reset_work); 943 struct net_device *dev = link->priv;
1021 } 944 struct orinoco_private *priv = netdev_priv(dev);
1022 break; 945
946 link->state &= ~DEV_SUSPEND;
947 if (link->state & DEV_CONFIG) {
948 /* FIXME: should we double check that this is
949 * the same card as we had before */
950 pcmcia_request_configuration(link->handle, &link->conf);
951 netif_device_attach(dev);
952 priv->hw_unavailable--;
953 schedule_work(&priv->reset_work);
1023 } 954 }
955 return 0;
956}
1024 957
1025 return err;
1026} /* spectrum_cs_event */
1027 958
1028/********************************************************************/ 959/********************************************************************/
1029/* Module initialization */ 960/* Module initialization */
@@ -1048,9 +979,10 @@ static struct pcmcia_driver orinoco_driver = {
1048 .drv = { 979 .drv = {
1049 .name = DRIVER_NAME, 980 .name = DRIVER_NAME,
1050 }, 981 },
1051 .attach = spectrum_cs_attach, 982 .probe = spectrum_cs_attach,
1052 .detach = spectrum_cs_detach, 983 .remove = spectrum_cs_detach,
1053 .event = spectrum_cs_event, 984 .suspend = spectrum_cs_suspend,
985 .resume = spectrum_cs_resume,
1054 .id_table = spectrum_cs_ids, 986 .id_table = spectrum_cs_ids,
1055}; 987};
1056 988
@@ -1066,7 +998,6 @@ static void __exit
1066exit_spectrum_cs(void) 998exit_spectrum_cs(void)
1067{ 999{
1068 pcmcia_unregister_driver(&orinoco_driver); 1000 pcmcia_unregister_driver(&orinoco_driver);
1069 BUG_ON(dev_list != NULL);
1070} 1001}
1071 1002
1072module_init(init_spectrum_cs); 1003module_init(init_spectrum_cs);
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index c822cad3333f..7e2039f52c49 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -4594,14 +4594,12 @@ wavelan_close(struct net_device * dev)
4594 * configure the card at this point -- we wait until we receive a 4594 * configure the card at this point -- we wait until we receive a
4595 * card insertion event. 4595 * card insertion event.
4596 */ 4596 */
4597static dev_link_t * 4597static int
4598wavelan_attach(void) 4598wavelan_attach(struct pcmcia_device *p_dev)
4599{ 4599{
4600 client_reg_t client_reg; /* Register with cardmgr */
4601 dev_link_t * link; /* Info for cardmgr */ 4600 dev_link_t * link; /* Info for cardmgr */
4602 struct net_device * dev; /* Interface generic data */ 4601 struct net_device * dev; /* Interface generic data */
4603 net_local * lp; /* Interface specific data */ 4602 net_local * lp; /* Interface specific data */
4604 int ret;
4605 4603
4606#ifdef DEBUG_CALLBACK_TRACE 4604#ifdef DEBUG_CALLBACK_TRACE
4607 printk(KERN_DEBUG "-> wavelan_attach()\n"); 4605 printk(KERN_DEBUG "-> wavelan_attach()\n");
@@ -4609,7 +4607,7 @@ wavelan_attach(void)
4609 4607
4610 /* Initialize the dev_link_t structure */ 4608 /* Initialize the dev_link_t structure */
4611 link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL); 4609 link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
4612 if (!link) return NULL; 4610 if (!link) return -ENOMEM;
4613 4611
4614 /* The io structure describes IO port mapping */ 4612 /* The io structure describes IO port mapping */
4615 link->io.NumPorts1 = 8; 4613 link->io.NumPorts1 = 8;
@@ -4627,14 +4625,13 @@ wavelan_attach(void)
4627 link->conf.IntType = INT_MEMORY_AND_IO; 4625 link->conf.IntType = INT_MEMORY_AND_IO;
4628 4626
4629 /* Chain drivers */ 4627 /* Chain drivers */
4630 link->next = dev_list; 4628 link->next = NULL;
4631 dev_list = link;
4632 4629
4633 /* Allocate the generic data structure */ 4630 /* Allocate the generic data structure */
4634 dev = alloc_etherdev(sizeof(net_local)); 4631 dev = alloc_etherdev(sizeof(net_local));
4635 if (!dev) { 4632 if (!dev) {
4636 kfree(link); 4633 kfree(link);
4637 return NULL; 4634 return -ENOMEM;
4638 } 4635 }
4639 link->priv = link->irq.Instance = dev; 4636 link->priv = link->irq.Instance = dev;
4640 4637
@@ -4679,28 +4676,21 @@ wavelan_attach(void)
4679 /* Other specific data */ 4676 /* Other specific data */
4680 dev->mtu = WAVELAN_MTU; 4677 dev->mtu = WAVELAN_MTU;
4681 4678
4682 /* Register with Card Services */ 4679 link->handle = p_dev;
4683 client_reg.dev_info = &dev_info; 4680 p_dev->instance = link;
4684 client_reg.Version = 0x0210;
4685 client_reg.event_callback_args.client_data = link;
4686 4681
4687#ifdef DEBUG_CONFIG_INFO 4682 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
4688 printk(KERN_DEBUG "wavelan_attach(): almost done, calling pcmcia_register_client\n"); 4683 if(wv_pcmcia_config(link) &&
4689#endif 4684 wv_hw_config(dev))
4690 4685 wv_init_info(dev);
4691 ret = pcmcia_register_client(&link->handle, &client_reg); 4686 else
4692 if(ret != 0) 4687 dev->irq = 0;
4693 {
4694 cs_error(link->handle, RegisterClient, ret);
4695 wavelan_detach(link);
4696 return NULL;
4697 }
4698 4688
4699#ifdef DEBUG_CALLBACK_TRACE 4689#ifdef DEBUG_CALLBACK_TRACE
4700 printk(KERN_DEBUG "<- wavelan_attach()\n"); 4690 printk(KERN_DEBUG "<- wavelan_attach()\n");
4701#endif 4691#endif
4702 4692
4703 return link; 4693 return 0;
4704} 4694}
4705 4695
4706/*------------------------------------------------------------------*/ 4696/*------------------------------------------------------------------*/
@@ -4711,8 +4701,10 @@ wavelan_attach(void)
4711 * is released. 4701 * is released.
4712 */ 4702 */
4713static void 4703static void
4714wavelan_detach(dev_link_t * link) 4704wavelan_detach(struct pcmcia_device *p_dev)
4715{ 4705{
4706 dev_link_t *link = dev_to_instance(p_dev);
4707
4716#ifdef DEBUG_CALLBACK_TRACE 4708#ifdef DEBUG_CALLBACK_TRACE
4717 printk(KERN_DEBUG "-> wavelan_detach(0x%p)\n", link); 4709 printk(KERN_DEBUG "-> wavelan_detach(0x%p)\n", link);
4718#endif 4710#endif
@@ -4729,31 +4721,6 @@ wavelan_detach(dev_link_t * link)
4729 wv_pcmcia_release(link); 4721 wv_pcmcia_release(link);
4730 } 4722 }
4731 4723
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 */
4737 if(dev_list == link)
4738 dev_list = link->next;
4739 else
4740 {
4741 dev_link_t * prev = dev_list;
4742
4743 while((prev != (dev_link_t *) NULL) && (prev->next != link))
4744 prev = prev->next;
4745
4746 if(prev == (dev_link_t *) NULL)
4747 {
4748#ifdef DEBUG_CONFIG_ERRORS
4749 printk(KERN_WARNING "wavelan_detach : Attempting to remove a nonexistent device.\n");
4750#endif
4751 return;
4752 }
4753
4754 prev->next = link->next;
4755 }
4756
4757 /* Free pieces */ 4724 /* Free pieces */
4758 if(link->priv) 4725 if(link->priv)
4759 { 4726 {
@@ -4775,65 +4742,11 @@ wavelan_detach(dev_link_t * link)
4775#endif 4742#endif
4776} 4743}
4777 4744
4778/*------------------------------------------------------------------*/ 4745static int wavelan_suspend(struct pcmcia_device *p_dev)
4779/*
4780 * The card status event handler. Mostly, this schedules other stuff
4781 * to run after an event is received. A CARD_REMOVAL event also sets
4782 * some flags to discourage the net drivers from trying to talk to the
4783 * card any more.
4784 */
4785static int
4786wavelan_event(event_t event, /* The event received */
4787 int priority,
4788 event_callback_args_t * args)
4789{ 4746{
4790 dev_link_t * link = (dev_link_t *) args->client_data; 4747 dev_link_t *link = dev_to_instance(p_dev);
4791 struct net_device * dev = (struct net_device *) link->priv; 4748 struct net_device * dev = (struct net_device *) link->priv;
4792
4793#ifdef DEBUG_CALLBACK_TRACE
4794 printk(KERN_DEBUG "->wavelan_event(): %s\n",
4795 ((event == CS_EVENT_REGISTRATION_COMPLETE)?"registration complete" :
4796 ((event == CS_EVENT_CARD_REMOVAL) ? "card removal" :
4797 ((event == CS_EVENT_CARD_INSERTION) ? "card insertion" :
4798 ((event == CS_EVENT_PM_SUSPEND) ? "pm suspend" :
4799 ((event == CS_EVENT_RESET_PHYSICAL) ? "physical reset" :
4800 ((event == CS_EVENT_PM_RESUME) ? "pm resume" :
4801 ((event == CS_EVENT_CARD_RESET) ? "card reset" :
4802 "unknown"))))))));
4803#endif
4804
4805 switch(event)
4806 {
4807 case CS_EVENT_REGISTRATION_COMPLETE:
4808#ifdef DEBUG_CONFIG_INFO
4809 printk(KERN_DEBUG "wavelan_cs: registration complete\n");
4810#endif
4811 break;
4812 4749
4813 case CS_EVENT_CARD_REMOVAL:
4814 /* Oups ! The card is no more there */
4815 link->state &= ~DEV_PRESENT;
4816 if(link->state & DEV_CONFIG)
4817 {
4818 /* Accept no more transmissions */
4819 netif_device_detach(dev);
4820
4821 /* Release the card */
4822 wv_pcmcia_release(link);
4823 }
4824 break;
4825
4826 case CS_EVENT_CARD_INSERTION:
4827 /* Reset and configure the card */
4828 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
4829 if(wv_pcmcia_config(link) &&
4830 wv_hw_config(dev))
4831 wv_init_info(dev);
4832 else
4833 dev->irq = 0;
4834 break;
4835
4836 case CS_EVENT_PM_SUSPEND:
4837 /* NB: wavelan_close will be called, but too late, so we are 4750 /* NB: wavelan_close will be called, but too late, so we are
4838 * obliged to close nicely the wavelan here. David, could you 4751 * obliged to close nicely the wavelan here. David, could you
4839 * close the device before suspending them ? And, by the way, 4752 * close the device before suspending them ? And, by the way,
@@ -4848,38 +4761,37 @@ wavelan_event(event_t event, /* The event received */
4848 4761
4849 /* The card is now suspended */ 4762 /* The card is now suspended */
4850 link->state |= DEV_SUSPEND; 4763 link->state |= DEV_SUSPEND;
4851 /* Fall through... */ 4764
4852 case CS_EVENT_RESET_PHYSICAL:
4853 if(link->state & DEV_CONFIG) 4765 if(link->state & DEV_CONFIG)
4854 { 4766 {
4855 if(link->open) 4767 if(link->open)
4856 netif_device_detach(dev); 4768 netif_device_detach(dev);
4857 pcmcia_release_configuration(link->handle); 4769 pcmcia_release_configuration(link->handle);
4858 } 4770 }
4859 break; 4771
4772 return 0;
4773}
4774
4775static int wavelan_resume(struct pcmcia_device *p_dev)
4776{
4777 dev_link_t *link = dev_to_instance(p_dev);
4778 struct net_device * dev = (struct net_device *) link->priv;
4860 4779
4861 case CS_EVENT_PM_RESUME:
4862 link->state &= ~DEV_SUSPEND; 4780 link->state &= ~DEV_SUSPEND;
4863 /* Fall through... */
4864 case CS_EVENT_CARD_RESET:
4865 if(link->state & DEV_CONFIG) 4781 if(link->state & DEV_CONFIG)
4866 { 4782 {
4867 pcmcia_request_configuration(link->handle, &link->conf); 4783 pcmcia_request_configuration(link->handle, &link->conf);
4868 if(link->open) /* If RESET -> True, If RESUME -> False ? */ 4784 if(link->open) /* If RESET -> True, If RESUME -> False ? */
4869 { 4785 {
4870 wv_hw_reset(dev); 4786 wv_hw_reset(dev);
4871 netif_device_attach(dev); 4787 netif_device_attach(dev);
4872 } 4788 }
4873 } 4789 }
4874 break;
4875 }
4876 4790
4877#ifdef DEBUG_CALLBACK_TRACE 4791 return 0;
4878 printk(KERN_DEBUG "<-wavelan_event()\n");
4879#endif
4880 return 0;
4881} 4792}
4882 4793
4794
4883static struct pcmcia_device_id wavelan_ids[] = { 4795static struct pcmcia_device_id wavelan_ids[] = {
4884 PCMCIA_DEVICE_PROD_ID12("AT&T","WaveLAN/PCMCIA", 0xe7c5affd, 0x1bc50975), 4796 PCMCIA_DEVICE_PROD_ID12("AT&T","WaveLAN/PCMCIA", 0xe7c5affd, 0x1bc50975),
4885 PCMCIA_DEVICE_PROD_ID12("Digital", "RoamAbout/DS", 0x9999ab35, 0x00d05e06), 4797 PCMCIA_DEVICE_PROD_ID12("Digital", "RoamAbout/DS", 0x9999ab35, 0x00d05e06),
@@ -4894,10 +4806,11 @@ static struct pcmcia_driver wavelan_driver = {
4894 .drv = { 4806 .drv = {
4895 .name = "wavelan_cs", 4807 .name = "wavelan_cs",
4896 }, 4808 },
4897 .attach = wavelan_attach, 4809 .probe = wavelan_attach,
4898 .event = wavelan_event, 4810 .remove = wavelan_detach,
4899 .detach = wavelan_detach,
4900 .id_table = wavelan_ids, 4811 .id_table = wavelan_ids,
4812 .suspend = wavelan_suspend,
4813 .resume = wavelan_resume,
4901}; 4814};
4902 4815
4903static int __init 4816static int __init
diff --git a/drivers/net/wireless/wavelan_cs.p.h b/drivers/net/wireless/wavelan_cs.p.h
index 724a715089c9..f2d597568151 100644
--- a/drivers/net/wireless/wavelan_cs.p.h
+++ b/drivers/net/wireless/wavelan_cs.p.h
@@ -754,20 +754,11 @@ static void
754static int 754static int
755 wavelan_open(struct net_device *), /* Open the device */ 755 wavelan_open(struct net_device *), /* Open the device */
756 wavelan_close(struct net_device *); /* Close the device */ 756 wavelan_close(struct net_device *); /* Close the device */
757static dev_link_t *
758 wavelan_attach(void); /* Create a new device */
759static void 757static void
760 wavelan_detach(dev_link_t *); /* Destroy a removed device */ 758 wavelan_detach(struct pcmcia_device *p_dev); /* Destroy a removed device */
761static int
762 wavelan_event(event_t, /* Manage pcmcia events */
763 int,
764 event_callback_args_t *);
765 759
766/**************************** VARIABLES ****************************/ 760/**************************** VARIABLES ****************************/
767 761
768static dev_info_t dev_info = "wavelan_cs";
769static dev_link_t *dev_list = NULL; /* Linked list of devices */
770
771/* 762/*
772 * Parameters that can be set with 'insmod' 763 * Parameters that can be set with 'insmod'
773 * The exact syntax is 'insmod wavelan_cs.o <var>=<value>' 764 * The exact syntax is 'insmod wavelan_cs.o <var>=<value>'
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index 978fdc606781..48e10b0c7e74 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -105,7 +105,6 @@ module_param(pc_debug, int, 0);
105 */ 105 */
106static void wl3501_config(dev_link_t *link); 106static void wl3501_config(dev_link_t *link);
107static void wl3501_release(dev_link_t *link); 107static void wl3501_release(dev_link_t *link);
108static int wl3501_event(event_t event, int pri, event_callback_args_t *args);
109 108
110/* 109/*
111 * The dev_info variable is the "key" that is used to match up this 110 * The dev_info variable is the "key" that is used to match up this
@@ -1498,9 +1497,11 @@ static struct ethtool_ops ops = {
1498 * Services. If it has been released, all local data structures are freed. 1497 * Services. If it has been released, all local data structures are freed.
1499 * Otherwise, the structures will be freed when the device is released. 1498 * Otherwise, the structures will be freed when the device is released.
1500 */ 1499 */
1501static void wl3501_detach(dev_link_t *link) 1500static void wl3501_detach(struct pcmcia_device *p_dev)
1502{ 1501{
1502 dev_link_t *link = dev_to_instance(p_dev);
1503 dev_link_t **linkp; 1503 dev_link_t **linkp;
1504 struct net_device *dev = link->priv;
1504 1505
1505 /* Locate device structure */ 1506 /* Locate device structure */
1506 for (linkp = &wl3501_dev_list; *linkp; linkp = &(*linkp)->next) 1507 for (linkp = &wl3501_dev_list; *linkp; linkp = &(*linkp)->next)
@@ -1514,16 +1515,12 @@ static void wl3501_detach(dev_link_t *link)
1514 * function is called, that will trigger a proper detach(). */ 1515 * function is called, that will trigger a proper detach(). */
1515 1516
1516 if (link->state & DEV_CONFIG) { 1517 if (link->state & DEV_CONFIG) {
1517#ifdef PCMCIA_DEBUG 1518 while (link->open > 0)
1518 printk(KERN_DEBUG "wl3501_cs: detach postponed, '%s' " 1519 wl3501_close(dev);
1519 "still locked\n", link->dev->dev_name);
1520#endif
1521 goto out;
1522 }
1523 1520
1524 /* Break the link with Card Services */ 1521 netif_device_detach(dev);
1525 if (link->handle) 1522 wl3501_release(link);
1526 pcmcia_deregister_client(link->handle); 1523 }
1527 1524
1528 /* Unlink device structure, free pieces */ 1525 /* Unlink device structure, free pieces */
1529 *linkp = link->next; 1526 *linkp = link->next;
@@ -1956,18 +1953,16 @@ static const struct iw_handler_def wl3501_handler_def = {
1956 * The dev_link structure is initialized, but we don't actually configure the 1953 * The dev_link structure is initialized, but we don't actually configure the
1957 * card at this point -- we wait until we receive a card insertion event. 1954 * card at this point -- we wait until we receive a card insertion event.
1958 */ 1955 */
1959static dev_link_t *wl3501_attach(void) 1956static int wl3501_attach(struct pcmcia_device *p_dev)
1960{ 1957{
1961 client_reg_t client_reg;
1962 dev_link_t *link; 1958 dev_link_t *link;
1963 struct net_device *dev; 1959 struct net_device *dev;
1964 struct wl3501_card *this; 1960 struct wl3501_card *this;
1965 int ret;
1966 1961
1967 /* Initialize the dev_link_t structure */ 1962 /* Initialize the dev_link_t structure */
1968 link = kzalloc(sizeof(*link), GFP_KERNEL); 1963 link = kzalloc(sizeof(*link), GFP_KERNEL);
1969 if (!link) 1964 if (!link)
1970 goto out; 1965 return -ENOMEM;
1971 1966
1972 /* The io structure describes IO port mapping */ 1967 /* The io structure describes IO port mapping */
1973 link->io.NumPorts1 = 16; 1968 link->io.NumPorts1 = 16;
@@ -2003,24 +1998,17 @@ static dev_link_t *wl3501_attach(void)
2003 netif_stop_queue(dev); 1998 netif_stop_queue(dev);
2004 link->priv = link->irq.Instance = dev; 1999 link->priv = link->irq.Instance = dev;
2005 2000
2006 /* Register with Card Services */ 2001 link->handle = p_dev;
2007 link->next = wl3501_dev_list; 2002 p_dev->instance = link;
2008 wl3501_dev_list = link; 2003
2009 client_reg.dev_info = &wl3501_dev_info; 2004 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
2010 client_reg.Version = 0x0210; 2005 wl3501_config(link);
2011 client_reg.event_callback_args.client_data = link; 2006
2012 ret = pcmcia_register_client(&link->handle, &client_reg); 2007 return 0;
2013 if (ret) {
2014 cs_error(link->handle, RegisterClient, ret);
2015 wl3501_detach(link);
2016 link = NULL;
2017 }
2018out:
2019 return link;
2020out_link: 2008out_link:
2021 kfree(link); 2009 kfree(link);
2022 link = NULL; 2010 link = NULL;
2023 goto out; 2011 return -ENOMEM;
2024} 2012}
2025 2013
2026#define CS_CHECK(fn, ret) \ 2014#define CS_CHECK(fn, ret) \
@@ -2173,67 +2161,41 @@ static void wl3501_release(dev_link_t *link)
2173 link->state &= ~DEV_CONFIG; 2161 link->state &= ~DEV_CONFIG;
2174} 2162}
2175 2163
2176/** 2164static int wl3501_suspend(struct pcmcia_device *p_dev)
2177 * wl3501_event - The card status event handler
2178 * @event - event
2179 * @pri - priority
2180 * @args - arguments for this event
2181 *
2182 * The card status event handler. Mostly, this schedules other stuff to run
2183 * after an event is received. A CARD_REMOVAL event also sets some flags to
2184 * discourage the net drivers from trying to talk to the card any more.
2185 *
2186 * When a CARD_REMOVAL event is received, we immediately set a flag to block
2187 * future accesses to this device. All the functions that actually access the
2188 * device should check this flag to make sure the card is still present.
2189 */
2190static int wl3501_event(event_t event, int pri, event_callback_args_t *args)
2191{ 2165{
2192 dev_link_t *link = args->client_data; 2166 dev_link_t *link = dev_to_instance(p_dev);
2193 struct net_device *dev = link->priv; 2167 struct net_device *dev = link->priv;
2194 2168
2195 switch (event) { 2169 link->state |= DEV_SUSPEND;
2196 case CS_EVENT_CARD_REMOVAL: 2170
2197 link->state &= ~DEV_PRESENT; 2171 wl3501_pwr_mgmt(dev->priv, WL3501_SUSPEND);
2198 if (link->state & DEV_CONFIG) { 2172 if (link->state & DEV_CONFIG) {
2199 while (link->open > 0) 2173 if (link->open)
2200 wl3501_close(dev);
2201 netif_device_detach(dev); 2174 netif_device_detach(dev);
2202 wl3501_release(link); 2175 pcmcia_release_configuration(link->handle);
2203 } 2176 }
2204 break; 2177
2205 case CS_EVENT_CARD_INSERTION: 2178 return 0;
2206 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 2179}
2207 wl3501_config(link); 2180
2208 break; 2181static int wl3501_resume(struct pcmcia_device *p_dev)
2209 case CS_EVENT_PM_SUSPEND: 2182{
2210 link->state |= DEV_SUSPEND; 2183 dev_link_t *link = dev_to_instance(p_dev);
2211 wl3501_pwr_mgmt(dev->priv, WL3501_SUSPEND); 2184 struct net_device *dev = link->priv;
2212 /* Fall through... */ 2185
2213 case CS_EVENT_RESET_PHYSICAL: 2186 wl3501_pwr_mgmt(dev->priv, WL3501_RESUME);
2214 if (link->state & DEV_CONFIG) { 2187 if (link->state & DEV_CONFIG) {
2215 if (link->open) 2188 pcmcia_request_configuration(link->handle, &link->conf);
2216 netif_device_detach(dev); 2189 if (link->open) {
2217 pcmcia_release_configuration(link->handle); 2190 wl3501_reset(dev);
2218 } 2191 netif_device_attach(dev);
2219 break;
2220 case CS_EVENT_PM_RESUME:
2221 link->state &= ~DEV_SUSPEND;
2222 wl3501_pwr_mgmt(dev->priv, WL3501_RESUME);
2223 /* Fall through... */
2224 case CS_EVENT_CARD_RESET:
2225 if (link->state & DEV_CONFIG) {
2226 pcmcia_request_configuration(link->handle, &link->conf);
2227 if (link->open) {
2228 wl3501_reset(dev);
2229 netif_device_attach(dev);
2230 }
2231 } 2192 }
2232 break;
2233 } 2193 }
2194
2234 return 0; 2195 return 0;
2235} 2196}
2236 2197
2198
2237static struct pcmcia_device_id wl3501_ids[] = { 2199static struct pcmcia_device_id wl3501_ids[] = {
2238 PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0001), 2200 PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0001),
2239 PCMCIA_DEVICE_NULL 2201 PCMCIA_DEVICE_NULL
@@ -2245,10 +2207,11 @@ static struct pcmcia_driver wl3501_driver = {
2245 .drv = { 2207 .drv = {
2246 .name = "wl3501_cs", 2208 .name = "wl3501_cs",
2247 }, 2209 },
2248 .attach = wl3501_attach, 2210 .probe = wl3501_attach,
2249 .event = wl3501_event, 2211 .remove = wl3501_detach,
2250 .detach = wl3501_detach,
2251 .id_table = wl3501_ids, 2212 .id_table = wl3501_ids,
2213 .suspend = wl3501_suspend,
2214 .resume = wl3501_resume,
2252}; 2215};
2253 2216
2254static int __init wl3501_init_module(void) 2217static int __init wl3501_init_module(void)
diff --git a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c
index 24e6aacddb74..158d92563259 100644
--- a/drivers/parport/parport_cs.c
+++ b/drivers/parport/parport_cs.c
@@ -87,15 +87,9 @@ typedef struct parport_info_t {
87 struct parport *port; 87 struct parport *port;
88} parport_info_t; 88} parport_info_t;
89 89
90static dev_link_t *parport_attach(void); 90static void parport_detach(struct pcmcia_device *p_dev);
91static void parport_detach(dev_link_t *);
92static void parport_config(dev_link_t *link); 91static void parport_config(dev_link_t *link);
93static void parport_cs_release(dev_link_t *); 92static void parport_cs_release(dev_link_t *);
94static int parport_event(event_t event, int priority,
95 event_callback_args_t *args);
96
97static dev_info_t dev_info = "parport_cs";
98static dev_link_t *dev_list = NULL;
99 93
100/*====================================================================== 94/*======================================================================
101 95
@@ -105,18 +99,16 @@ static dev_link_t *dev_list = NULL;
105 99
106======================================================================*/ 100======================================================================*/
107 101
108static dev_link_t *parport_attach(void) 102static int parport_attach(struct pcmcia_device *p_dev)
109{ 103{
110 parport_info_t *info; 104 parport_info_t *info;
111 dev_link_t *link; 105 dev_link_t *link;
112 client_reg_t client_reg; 106
113 int ret;
114
115 DEBUG(0, "parport_attach()\n"); 107 DEBUG(0, "parport_attach()\n");
116 108
117 /* Create new parport device */ 109 /* Create new parport device */
118 info = kmalloc(sizeof(*info), GFP_KERNEL); 110 info = kmalloc(sizeof(*info), GFP_KERNEL);
119 if (!info) return NULL; 111 if (!info) return -ENOMEM;
120 memset(info, 0, sizeof(*info)); 112 memset(info, 0, sizeof(*info));
121 link = &info->link; link->priv = info; 113 link = &info->link; link->priv = info;
122 114
@@ -127,21 +119,14 @@ static dev_link_t *parport_attach(void)
127 link->conf.Attributes = CONF_ENABLE_IRQ; 119 link->conf.Attributes = CONF_ENABLE_IRQ;
128 link->conf.Vcc = 50; 120 link->conf.Vcc = 50;
129 link->conf.IntType = INT_MEMORY_AND_IO; 121 link->conf.IntType = INT_MEMORY_AND_IO;
130 122
131 /* Register with Card Services */ 123 link->handle = p_dev;
132 link->next = dev_list; 124 p_dev->instance = link;
133 dev_list = link; 125
134 client_reg.dev_info = &dev_info; 126 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
135 client_reg.Version = 0x0210; 127 parport_config(link);
136 client_reg.event_callback_args.client_data = link; 128
137 ret = pcmcia_register_client(&link->handle, &client_reg); 129 return 0;
138 if (ret != CS_SUCCESS) {
139 cs_error(link->handle, RegisterClient, ret);
140 parport_detach(link);
141 return NULL;
142 }
143
144 return link;
145} /* parport_attach */ 130} /* parport_attach */
146 131
147/*====================================================================== 132/*======================================================================
@@ -153,32 +138,16 @@ static dev_link_t *parport_attach(void)
153 138
154======================================================================*/ 139======================================================================*/
155 140
156static void parport_detach(dev_link_t *link) 141static void parport_detach(struct pcmcia_device *p_dev)
157{ 142{
158 dev_link_t **linkp; 143 dev_link_t *link = dev_to_instance(p_dev);
159 int ret;
160 144
161 DEBUG(0, "parport_detach(0x%p)\n", link); 145 DEBUG(0, "parport_detach(0x%p)\n", link);
162
163 /* Locate device structure */
164 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
165 if (*linkp == link) break;
166 if (*linkp == NULL)
167 return;
168 146
169 if (link->state & DEV_CONFIG) 147 if (link->state & DEV_CONFIG)
170 parport_cs_release(link); 148 parport_cs_release(link);
171 149
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 */
179 *linkp = link->next;
180 kfree(link->priv); 150 kfree(link->priv);
181
182} /* parport_detach */ 151} /* parport_detach */
183 152
184/*====================================================================== 153/*======================================================================
@@ -325,47 +294,27 @@ void parport_cs_release(dev_link_t *link)
325 294
326} /* parport_cs_release */ 295} /* parport_cs_release */
327 296
328/*====================================================================== 297static int parport_suspend(struct pcmcia_device *dev)
329
330 The card status event handler. Mostly, this schedules other
331 stuff to run after an event is received.
332
333======================================================================*/
334
335int parport_event(event_t event, int priority,
336 event_callback_args_t *args)
337{ 298{
338 dev_link_t *link = args->client_data; 299 dev_link_t *link = dev_to_instance(dev);
339 300
340 DEBUG(1, "parport_event(0x%06x)\n", event);
341
342 switch (event) {
343 case CS_EVENT_CARD_REMOVAL:
344 link->state &= ~DEV_PRESENT;
345 if (link->state & DEV_CONFIG)
346 parport_cs_release(link);
347 break;
348 case CS_EVENT_CARD_INSERTION:
349 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
350 parport_config(link);
351 break;
352 case CS_EVENT_PM_SUSPEND:
353 link->state |= DEV_SUSPEND; 301 link->state |= DEV_SUSPEND;
354 /* Fall through... */
355 case CS_EVENT_RESET_PHYSICAL:
356 if (link->state & DEV_CONFIG) 302 if (link->state & DEV_CONFIG)
357 pcmcia_release_configuration(link->handle); 303 pcmcia_release_configuration(link->handle);
358 break; 304
359 case CS_EVENT_PM_RESUME: 305 return 0;
306}
307
308static int parport_resume(struct pcmcia_device *dev)
309{
310 dev_link_t *link = dev_to_instance(dev);
311
360 link->state &= ~DEV_SUSPEND; 312 link->state &= ~DEV_SUSPEND;
361 /* Fall through... */
362 case CS_EVENT_CARD_RESET:
363 if (DEV_OK(link)) 313 if (DEV_OK(link))
364 pcmcia_request_configuration(link->handle, &link->conf); 314 pcmcia_request_configuration(link->handle, &link->conf);
365 break; 315
366 } 316 return 0;
367 return 0; 317}
368} /* parport_event */
369 318
370static struct pcmcia_device_id parport_ids[] = { 319static struct pcmcia_device_id parport_ids[] = {
371 PCMCIA_DEVICE_FUNC_ID(3), 320 PCMCIA_DEVICE_FUNC_ID(3),
@@ -379,11 +328,11 @@ static struct pcmcia_driver parport_cs_driver = {
379 .drv = { 328 .drv = {
380 .name = "parport_cs", 329 .name = "parport_cs",
381 }, 330 },
382 .attach = parport_attach, 331 .probe = parport_attach,
383 .event = parport_event, 332 .remove = parport_detach,
384 .detach = parport_detach,
385 .id_table = parport_ids, 333 .id_table = parport_ids,
386 334 .suspend = parport_suspend,
335 .resume = parport_resume,
387}; 336};
388 337
389static int __init init_parport_cs(void) 338static int __init init_parport_cs(void)
@@ -394,7 +343,6 @@ static int __init init_parport_cs(void)
394static void __exit exit_parport_cs(void) 343static void __exit exit_parport_cs(void)
395{ 344{
396 pcmcia_unregister_driver(&parport_cs_driver); 345 pcmcia_unregister_driver(&parport_cs_driver);
397 BUG_ON(dev_list != NULL);
398} 346}
399 347
400module_init(init_parport_cs); 348module_init(init_parport_cs);
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index 309eb557f9a3..1f4ad0e7836e 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -116,6 +116,31 @@ config YENTA
116 116
117 If unsure, say Y. 117 If unsure, say Y.
118 118
119config YENTA_O2
120 default y
121 bool "Special initialization for O2Micro bridges" if EMBEDDED
122 depends on YENTA
123
124config YENTA_RICOH
125 default y
126 bool "Special initialization for Ricoh bridges" if EMBEDDED
127 depends on YENTA
128
129config YENTA_TI
130 default y
131 bool "Special initialization for TI and EnE bridges" if EMBEDDED
132 depends on YENTA
133
134config YENTA_ENE_TUNE
135 default y
136 bool "Auto-tune EnE bridges for CB cards" if EMBEDDED
137 depends on YENTA_TI && CARDBUS
138
139config YENTA_TOSHIBA
140 default y
141 bool "Special initialization for Toshiba ToPIC bridges" if EMBEDDED
142 depends on YENTA
143
119config PD6729 144config PD6729
120 tristate "Cirrus PD6729 compatible bridge support" 145 tristate "Cirrus PD6729 compatible bridge support"
121 depends on PCMCIA && PCI 146 depends on PCMCIA && PCI
@@ -157,7 +182,7 @@ config TCIC
157config PCMCIA_M8XX 182config PCMCIA_M8XX
158 tristate "MPC8xx PCMCIA support" 183 tristate "MPC8xx PCMCIA support"
159 depends on PCMCIA && PPC && 8xx 184 depends on PCMCIA && PPC && 8xx
160 select PCCARD_NONSTATIC 185 select PCCARD_IODYN
161 help 186 help
162 Say Y here to include support for PowerPC 8xx series PCMCIA 187 Say Y here to include support for PowerPC 8xx series PCMCIA
163 controller. 188 controller.
@@ -200,7 +225,7 @@ config PCMCIA_PXA2XX
200 225
201config PCMCIA_PROBE 226config PCMCIA_PROBE
202 bool 227 bool
203 default y if ISA && !ARCH_SA1100 && !ARCH_CLPS711X 228 default y if ISA && !ARCH_SA1100 && !ARCH_CLPS711X && !PARISC
204 229
205config M32R_PCC 230config M32R_PCC
206 bool "M32R PCMCIA I/F" 231 bool "M32R PCMCIA I/F"
@@ -241,6 +266,9 @@ config OMAP_CF
241config PCCARD_NONSTATIC 266config PCCARD_NONSTATIC
242 tristate 267 tristate
243 268
269config PCCARD_IODYN
270 bool
271
244endif # PCCARD 272endif # PCCARD
245 273
246endmenu 274endmenu
diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c
index 87302c548c24..971a35281649 100644
--- a/drivers/pcmcia/au1000_generic.c
+++ b/drivers/pcmcia/au1000_generic.c
@@ -241,23 +241,6 @@ au1x00_pcmcia_get_status(struct pcmcia_socket *sock, unsigned int *status)
241 return 0; 241 return 0;
242} 242}
243 243
244/* au1x00_pcmcia_get_socket()
245 * Implements the get_socket() operation for the in-kernel PCMCIA
246 * service (formerly SS_GetSocket in Card Services). Not a very
247 * exciting routine.
248 *
249 * Returns: 0
250 */
251static int
252au1x00_pcmcia_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
253{
254 struct au1000_pcmcia_socket *skt = to_au1000_socket(sock);
255
256 debug("for sock %u\n", skt->nr);
257 *state = skt->cs_state;
258 return 0;
259}
260
261/* au1x00_pcmcia_set_socket() 244/* au1x00_pcmcia_set_socket()
262 * Implements the set_socket() operation for the in-kernel PCMCIA 245 * Implements the set_socket() operation for the in-kernel PCMCIA
263 * service (formerly SS_SetSocket in Card Services). We more or 246 * service (formerly SS_SetSocket in Card Services). We more or
@@ -352,7 +335,6 @@ static struct pccard_operations au1x00_pcmcia_operations = {
352 .init = au1x00_pcmcia_sock_init, 335 .init = au1x00_pcmcia_sock_init,
353 .suspend = au1x00_pcmcia_suspend, 336 .suspend = au1x00_pcmcia_suspend,
354 .get_status = au1x00_pcmcia_get_status, 337 .get_status = au1x00_pcmcia_get_status,
355 .get_socket = au1x00_pcmcia_get_socket,
356 .set_socket = au1x00_pcmcia_set_socket, 338 .set_socket = au1x00_pcmcia_set_socket,
357 .set_io_map = au1x00_pcmcia_set_io_map, 339 .set_io_map = au1x00_pcmcia_set_io_map,
358 .set_mem_map = au1x00_pcmcia_set_mem_map, 340 .set_mem_map = au1x00_pcmcia_set_mem_map,
@@ -372,13 +354,12 @@ int au1x00_pcmcia_socket_probe(struct device *dev, struct pcmcia_low_level *ops,
372 struct skt_dev_info *sinfo; 354 struct skt_dev_info *sinfo;
373 int ret, i; 355 int ret, i;
374 356
375 sinfo = kmalloc(sizeof(struct skt_dev_info), GFP_KERNEL); 357 sinfo = kzalloc(sizeof(struct skt_dev_info), GFP_KERNEL);
376 if (!sinfo) { 358 if (!sinfo) {
377 ret = -ENOMEM; 359 ret = -ENOMEM;
378 goto out; 360 goto out;
379 } 361 }
380 362
381 memset(sinfo, 0, sizeof(struct skt_dev_info));
382 sinfo->nskt = nr; 363 sinfo->nskt = nr;
383 364
384 /* 365 /*
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c
index 2dc3e611a9a3..120fa8da6392 100644
--- a/drivers/pcmcia/cistpl.c
+++ b/drivers/pcmcia/cistpl.c
@@ -60,9 +60,9 @@ static const u_int exponent[] = {
60 60
61/* Parameters that can be set with 'insmod' */ 61/* Parameters that can be set with 'insmod' */
62 62
63#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444) 63/* 16-bit CIS? */
64 64static int cis_width;
65INT_MODULE_PARM(cis_width, 0); /* 16-bit CIS? */ 65module_param(cis_width, int, 0444);
66 66
67void release_cis_mem(struct pcmcia_socket *s) 67void release_cis_mem(struct pcmcia_socket *s)
68{ 68{
@@ -463,7 +463,7 @@ static int follow_link(struct pcmcia_socket *s, tuple_t *tuple)
463 /* Get indirect link from the MFC tuple */ 463 /* Get indirect link from the MFC tuple */
464 read_cis_cache(s, LINK_SPACE(tuple->Flags), 464 read_cis_cache(s, LINK_SPACE(tuple->Flags),
465 tuple->LinkOffset, 5, link); 465 tuple->LinkOffset, 5, link);
466 ofs = le32_to_cpu(*(u_int *)(link+1)); 466 ofs = le32_to_cpu(*(__le32 *)(link+1));
467 SPACE(tuple->Flags) = (link[0] == CISTPL_MFC_ATTR); 467 SPACE(tuple->Flags) = (link[0] == CISTPL_MFC_ATTR);
468 /* Move to the next indirect link */ 468 /* Move to the next indirect link */
469 tuple->LinkOffset += 5; 469 tuple->LinkOffset += 5;
@@ -671,8 +671,8 @@ static int parse_checksum(tuple_t *tuple, cistpl_checksum_t *csum)
671 if (tuple->TupleDataLen < 5) 671 if (tuple->TupleDataLen < 5)
672 return CS_BAD_TUPLE; 672 return CS_BAD_TUPLE;
673 p = (u_char *)tuple->TupleData; 673 p = (u_char *)tuple->TupleData;
674 csum->addr = tuple->CISOffset+(short)le16_to_cpu(*(u_short *)p)-2; 674 csum->addr = tuple->CISOffset+(short)le16_to_cpu(*(__le16 *)p)-2;
675 csum->len = le16_to_cpu(*(u_short *)(p + 2)); 675 csum->len = le16_to_cpu(*(__le16 *)(p + 2));
676 csum->sum = *(p+4); 676 csum->sum = *(p+4);
677 return CS_SUCCESS; 677 return CS_SUCCESS;
678} 678}
@@ -683,7 +683,7 @@ static int parse_longlink(tuple_t *tuple, cistpl_longlink_t *link)
683{ 683{
684 if (tuple->TupleDataLen < 4) 684 if (tuple->TupleDataLen < 4)
685 return CS_BAD_TUPLE; 685 return CS_BAD_TUPLE;
686 link->addr = le32_to_cpu(*(u_int *)tuple->TupleData); 686 link->addr = le32_to_cpu(*(__le32 *)tuple->TupleData);
687 return CS_SUCCESS; 687 return CS_SUCCESS;
688} 688}
689 689
@@ -702,7 +702,7 @@ static int parse_longlink_mfc(tuple_t *tuple,
702 return CS_BAD_TUPLE; 702 return CS_BAD_TUPLE;
703 for (i = 0; i < link->nfn; i++) { 703 for (i = 0; i < link->nfn; i++) {
704 link->fn[i].space = *p; p++; 704 link->fn[i].space = *p; p++;
705 link->fn[i].addr = le32_to_cpu(*(u_int *)p); p += 4; 705 link->fn[i].addr = le32_to_cpu(*(__le32 *)p); p += 4;
706 } 706 }
707 return CS_SUCCESS; 707 return CS_SUCCESS;
708} 708}
@@ -789,10 +789,10 @@ static int parse_jedec(tuple_t *tuple, cistpl_jedec_t *jedec)
789 789
790static int parse_manfid(tuple_t *tuple, cistpl_manfid_t *m) 790static int parse_manfid(tuple_t *tuple, cistpl_manfid_t *m)
791{ 791{
792 u_short *p; 792 __le16 *p;
793 if (tuple->TupleDataLen < 4) 793 if (tuple->TupleDataLen < 4)
794 return CS_BAD_TUPLE; 794 return CS_BAD_TUPLE;
795 p = (u_short *)tuple->TupleData; 795 p = (__le16 *)tuple->TupleData;
796 m->manf = le16_to_cpu(p[0]); 796 m->manf = le16_to_cpu(p[0]);
797 m->card = le16_to_cpu(p[1]); 797 m->card = le16_to_cpu(p[1]);
798 return CS_SUCCESS; 798 return CS_SUCCESS;
@@ -1093,7 +1093,7 @@ static int parse_cftable_entry(tuple_t *tuple,
1093 break; 1093 break;
1094 case 0x20: 1094 case 0x20:
1095 entry->mem.nwin = 1; 1095 entry->mem.nwin = 1;
1096 entry->mem.win[0].len = le16_to_cpu(*(u_short *)p) << 8; 1096 entry->mem.win[0].len = le16_to_cpu(*(__le16 *)p) << 8;
1097 entry->mem.win[0].card_addr = 0; 1097 entry->mem.win[0].card_addr = 0;
1098 entry->mem.win[0].host_addr = 0; 1098 entry->mem.win[0].host_addr = 0;
1099 p += 2; 1099 p += 2;
@@ -1101,9 +1101,9 @@ static int parse_cftable_entry(tuple_t *tuple,
1101 break; 1101 break;
1102 case 0x40: 1102 case 0x40:
1103 entry->mem.nwin = 1; 1103 entry->mem.nwin = 1;
1104 entry->mem.win[0].len = le16_to_cpu(*(u_short *)p) << 8; 1104 entry->mem.win[0].len = le16_to_cpu(*(__le16 *)p) << 8;
1105 entry->mem.win[0].card_addr = 1105 entry->mem.win[0].card_addr =
1106 le16_to_cpu(*(u_short *)(p+2)) << 8; 1106 le16_to_cpu(*(__le16 *)(p+2)) << 8;
1107 entry->mem.win[0].host_addr = 0; 1107 entry->mem.win[0].host_addr = 0;
1108 p += 4; 1108 p += 4;
1109 if (p > q) return CS_BAD_TUPLE; 1109 if (p > q) return CS_BAD_TUPLE;
@@ -1140,7 +1140,7 @@ static int parse_bar(tuple_t *tuple, cistpl_bar_t *bar)
1140 p = (u_char *)tuple->TupleData; 1140 p = (u_char *)tuple->TupleData;
1141 bar->attr = *p; 1141 bar->attr = *p;
1142 p += 2; 1142 p += 2;
1143 bar->size = le32_to_cpu(*(u_int *)p); 1143 bar->size = le32_to_cpu(*(__le32 *)p);
1144 return CS_SUCCESS; 1144 return CS_SUCCESS;
1145} 1145}
1146 1146
@@ -1153,7 +1153,7 @@ static int parse_config_cb(tuple_t *tuple, cistpl_config_t *config)
1153 return CS_BAD_TUPLE; 1153 return CS_BAD_TUPLE;
1154 config->last_idx = *(++p); 1154 config->last_idx = *(++p);
1155 p++; 1155 p++;
1156 config->base = le32_to_cpu(*(u_int *)p); 1156 config->base = le32_to_cpu(*(__le32 *)p);
1157 config->subtuples = tuple->TupleDataLen - 6; 1157 config->subtuples = tuple->TupleDataLen - 6;
1158 return CS_SUCCESS; 1158 return CS_SUCCESS;
1159} 1159}
@@ -1269,7 +1269,7 @@ static int parse_vers_2(tuple_t *tuple, cistpl_vers_2_t *v2)
1269 1269
1270 v2->vers = p[0]; 1270 v2->vers = p[0];
1271 v2->comply = p[1]; 1271 v2->comply = p[1];
1272 v2->dindex = le16_to_cpu(*(u_short *)(p+2)); 1272 v2->dindex = le16_to_cpu(*(__le16 *)(p+2));
1273 v2->vspec8 = p[6]; 1273 v2->vspec8 = p[6];
1274 v2->vspec9 = p[7]; 1274 v2->vspec9 = p[7];
1275 v2->nhdr = p[8]; 1275 v2->nhdr = p[8];
@@ -1310,8 +1310,8 @@ static int parse_format(tuple_t *tuple, cistpl_format_t *fmt)
1310 1310
1311 fmt->type = p[0]; 1311 fmt->type = p[0];
1312 fmt->edc = p[1]; 1312 fmt->edc = p[1];
1313 fmt->offset = le32_to_cpu(*(u_int *)(p+2)); 1313 fmt->offset = le32_to_cpu(*(__le32 *)(p+2));
1314 fmt->length = le32_to_cpu(*(u_int *)(p+6)); 1314 fmt->length = le32_to_cpu(*(__le32 *)(p+6));
1315 1315
1316 return CS_SUCCESS; 1316 return CS_SUCCESS;
1317} 1317}
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index 7cf09084ef61..613f2f1fbfdd 100644
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -309,41 +309,6 @@ struct pcmcia_socket * pcmcia_get_socket_by_nr(unsigned int nr)
309} 309}
310EXPORT_SYMBOL(pcmcia_get_socket_by_nr); 310EXPORT_SYMBOL(pcmcia_get_socket_by_nr);
311 311
312
313/**
314 * socket_setup() and shutdown_socket() are called by the main event
315 * handler when card insertion and removal events are received.
316 * socket_setup() turns on socket power and resets the socket, in two stages.
317 * shutdown_socket() unconfigures a socket and turns off socket power.
318 */
319static void shutdown_socket(struct pcmcia_socket *s)
320{
321 cs_dbg(s, 1, "shutdown_socket\n");
322
323 /* Blank out the socket state */
324 s->socket = dead_socket;
325 s->ops->init(s);
326 s->ops->set_socket(s, &s->socket);
327 s->irq.AssignedIRQ = s->irq.Config = 0;
328 s->lock_count = 0;
329 destroy_cis_cache(s);
330#ifdef CONFIG_CARDBUS
331 cb_free(s);
332#endif
333 s->functions = 0;
334 kfree(s->config);
335 s->config = NULL;
336
337 {
338 int status;
339 s->ops->get_status(s, &status);
340 if (status & SS_POWERON) {
341 printk(KERN_ERR "PCMCIA: socket %p: *** DANGER *** unable to remove socket power\n", s);
342 }
343 }
344} /* shutdown_socket */
345
346
347/** 312/**
348 * The central event handler. Send_event() sends an event to the 313 * The central event handler. Send_event() sends an event to the
349 * 16-bit subsystem, which then calls the relevant device drivers. 314 * 16-bit subsystem, which then calls the relevant device drivers.
@@ -383,17 +348,6 @@ static void socket_remove_drivers(struct pcmcia_socket *skt)
383 send_event(skt, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH); 348 send_event(skt, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH);
384} 349}
385 350
386static void socket_shutdown(struct pcmcia_socket *skt)
387{
388 cs_dbg(skt, 4, "shutdown\n");
389
390 socket_remove_drivers(skt);
391 skt->state &= SOCKET_INUSE|SOCKET_PRESENT;
392 msleep(shutdown_delay * 10);
393 skt->state &= SOCKET_INUSE;
394 shutdown_socket(skt);
395}
396
397static int socket_reset(struct pcmcia_socket *skt) 351static int socket_reset(struct pcmcia_socket *skt)
398{ 352{
399 int status, i; 353 int status, i;
@@ -424,6 +378,45 @@ static int socket_reset(struct pcmcia_socket *skt)
424 return CS_GENERAL_FAILURE; 378 return CS_GENERAL_FAILURE;
425} 379}
426 380
381/**
382 * socket_setup() and socket_shutdown() are called by the main event handler
383 * when card insertion and removal events are received.
384 * socket_setup() turns on socket power and resets the socket, in two stages.
385 * socket_shutdown() unconfigures a socket and turns off socket power.
386 */
387static void socket_shutdown(struct pcmcia_socket *s)
388{
389 int status;
390
391 cs_dbg(s, 4, "shutdown\n");
392
393 socket_remove_drivers(s);
394 s->state &= SOCKET_INUSE | SOCKET_PRESENT;
395 msleep(shutdown_delay * 10);
396 s->state &= SOCKET_INUSE;
397
398 /* Blank out the socket state */
399 s->socket = dead_socket;
400 s->ops->init(s);
401 s->ops->set_socket(s, &s->socket);
402 s->irq.AssignedIRQ = s->irq.Config = 0;
403 s->lock_count = 0;
404 destroy_cis_cache(s);
405#ifdef CONFIG_CARDBUS
406 cb_free(s);
407#endif
408 s->functions = 0;
409 kfree(s->config);
410 s->config = NULL;
411
412 s->ops->get_status(s, &status);
413 if (status & SS_POWERON) {
414 printk(KERN_ERR "PCMCIA: socket %p: *** DANGER *** unable to remove socket power\n", s);
415 }
416
417 cs_socket_put(s);
418}
419
427static int socket_setup(struct pcmcia_socket *skt, int initial_delay) 420static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
428{ 421{
429 int status, i; 422 int status, i;
@@ -529,7 +522,6 @@ static int socket_insert(struct pcmcia_socket *skt)
529 send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW); 522 send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
530 } else { 523 } else {
531 socket_shutdown(skt); 524 socket_shutdown(skt);
532 cs_socket_put(skt);
533 } 525 }
534 526
535 return ret; 527 return ret;
@@ -593,7 +585,6 @@ static int socket_resume(struct pcmcia_socket *skt)
593 } 585 }
594 } else { 586 } else {
595 socket_shutdown(skt); 587 socket_shutdown(skt);
596 cs_socket_put(skt);
597 } 588 }
598 589
599 skt->state &= ~SOCKET_SUSPEND; 590 skt->state &= ~SOCKET_SUSPEND;
@@ -605,7 +596,6 @@ static void socket_remove(struct pcmcia_socket *skt)
605{ 596{
606 printk(KERN_NOTICE "pccard: card ejected from slot %d\n", skt->sock); 597 printk(KERN_NOTICE "pccard: card ejected from slot %d\n", skt->sock);
607 socket_shutdown(skt); 598 socket_shutdown(skt);
608 cs_socket_put(skt);
609} 599}
610 600
611/* 601/*
@@ -780,8 +770,13 @@ int pccard_reset_card(struct pcmcia_socket *skt)
780 ret = send_event(skt, CS_EVENT_RESET_REQUEST, CS_EVENT_PRI_LOW); 770 ret = send_event(skt, CS_EVENT_RESET_REQUEST, CS_EVENT_PRI_LOW);
781 if (ret == 0) { 771 if (ret == 0) {
782 send_event(skt, CS_EVENT_RESET_PHYSICAL, CS_EVENT_PRI_LOW); 772 send_event(skt, CS_EVENT_RESET_PHYSICAL, CS_EVENT_PRI_LOW);
783 if (socket_reset(skt) == CS_SUCCESS) 773 if (skt->callback)
774 skt->callback->suspend(skt);
775 if (socket_reset(skt) == CS_SUCCESS) {
784 send_event(skt, CS_EVENT_CARD_RESET, CS_EVENT_PRI_LOW); 776 send_event(skt, CS_EVENT_CARD_RESET, CS_EVENT_PRI_LOW);
777 if (skt->callback)
778 skt->callback->resume(skt);
779 }
785 } 780 }
786 781
787 ret = CS_SUCCESS; 782 ret = CS_SUCCESS;
@@ -812,6 +807,11 @@ int pcmcia_suspend_card(struct pcmcia_socket *skt)
812 ret = CS_UNSUPPORTED_FUNCTION; 807 ret = CS_UNSUPPORTED_FUNCTION;
813 break; 808 break;
814 } 809 }
810 if (skt->callback) {
811 ret = skt->callback->suspend(skt);
812 if (ret)
813 break;
814 }
815 ret = socket_suspend(skt); 815 ret = socket_suspend(skt);
816 } while (0); 816 } while (0);
817 up(&skt->skt_sem); 817 up(&skt->skt_sem);
@@ -838,6 +838,8 @@ int pcmcia_resume_card(struct pcmcia_socket *skt)
838 break; 838 break;
839 } 839 }
840 ret = socket_resume(skt); 840 ret = socket_resume(skt);
841 if (!ret && skt->callback)
842 skt->callback->resume(skt);
841 } while (0); 843 } while (0);
842 up(&skt->skt_sem); 844 up(&skt->skt_sem);
843 845
diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h
index 55867bc7f199..7b37eba35bf1 100644
--- a/drivers/pcmcia/cs_internal.h
+++ b/drivers/pcmcia/cs_internal.h
@@ -117,7 +117,7 @@ int verify_cis_cache(struct pcmcia_socket *s);
117int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, cisdata_t code, void *parse); 117int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, cisdata_t code, void *parse);
118 118
119/* In rsrc_mgr */ 119/* In rsrc_mgr */
120void pcmcia_validate_mem(struct pcmcia_socket *s); 120int pcmcia_validate_mem(struct pcmcia_socket *s);
121struct resource *pcmcia_find_io_region(unsigned long base, int num, unsigned long align, 121struct resource *pcmcia_find_io_region(unsigned long base, int num, unsigned long align,
122 struct pcmcia_socket *s); 122 struct pcmcia_socket *s);
123int pcmcia_adjust_io_region(struct resource *res, unsigned long r_start, 123int pcmcia_adjust_io_region(struct resource *res, unsigned long r_start,
@@ -143,6 +143,8 @@ struct pcmcia_callback{
143 struct module *owner; 143 struct module *owner;
144 int (*event) (struct pcmcia_socket *s, event_t event, int priority); 144 int (*event) (struct pcmcia_socket *s, event_t event, int priority);
145 void (*requery) (struct pcmcia_socket *s); 145 void (*requery) (struct pcmcia_socket *s);
146 int (*suspend) (struct pcmcia_socket *s);
147 int (*resume) (struct pcmcia_socket *s);
146}; 148};
147 149
148int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c); 150int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c);
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 6fb76399547e..0252582b91cd 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->probe || !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
@@ -266,12 +264,10 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
266 if (fw->size >= CISTPL_MAX_CIS_SIZE) 264 if (fw->size >= CISTPL_MAX_CIS_SIZE)
267 goto release; 265 goto release;
268 266
269 cis = kmalloc(sizeof(cisdump_t), GFP_KERNEL); 267 cis = kzalloc(sizeof(cisdump_t), GFP_KERNEL);
270 if (!cis) 268 if (!cis)
271 goto release; 269 goto release;
272 270
273 memset(cis, 0, sizeof(cisdump_t));
274
275 cis->Length = fw->size + 1; 271 cis->Length = fw->size + 1;
276 memcpy(cis->Data, fw->data, fw->size); 272 memcpy(cis->Data, fw->data, fw->size);
277 273
@@ -363,6 +359,7 @@ static int pcmcia_device_probe(struct device * dev)
363{ 359{
364 struct pcmcia_device *p_dev; 360 struct pcmcia_device *p_dev;
365 struct pcmcia_driver *p_drv; 361 struct pcmcia_driver *p_drv;
362 struct pcmcia_socket *s;
366 int ret = 0; 363 int ret = 0;
367 364
368 dev = get_device(dev); 365 dev = get_device(dev);
@@ -371,25 +368,38 @@ static int pcmcia_device_probe(struct device * dev)
371 368
372 p_dev = to_pcmcia_dev(dev); 369 p_dev = to_pcmcia_dev(dev);
373 p_drv = to_pcmcia_drv(dev->driver); 370 p_drv = to_pcmcia_drv(dev->driver);
371 s = p_dev->socket;
374 372
375 if (!try_module_get(p_drv->owner)) { 373 if ((!p_drv->probe) || (!try_module_get(p_drv->owner))) {
376 ret = -EINVAL; 374 ret = -EINVAL;
377 goto put_dev; 375 goto put_dev;
378 } 376 }
379 377
380 if (p_drv->attach) { 378 p_dev->state &= ~CLIENT_UNBOUND;
381 p_dev->instance = p_drv->attach(); 379
382 if ((!p_dev->instance) || (p_dev->state & CLIENT_UNBOUND)) { 380 /* set up the device configuration, if it hasn't been done before */
383 printk(KERN_NOTICE "ds: unable to create instance " 381 if (!s->functions) {
384 "of '%s'!\n", p_drv->drv.name); 382 cistpl_longlink_mfc_t mfc;
385 ret = -EINVAL; 383 if (pccard_read_tuple(s, p_dev->func, CISTPL_LONGLINK_MFC,
384 &mfc) == CS_SUCCESS)
385 s->functions = mfc.nfn;
386 else
387 s->functions = 1;
388 s->config = kzalloc(sizeof(config_t) * s->functions,
389 GFP_KERNEL);
390 if (!s->config) {
391 ret = -ENOMEM;
392 goto put_module;
386 } 393 }
387 } 394 }
388 395
396 ret = p_drv->probe(p_dev);
397
398 put_module:
389 if (ret) 399 if (ret)
390 module_put(p_drv->owner); 400 module_put(p_drv->owner);
391 put_dev: 401 put_dev:
392 if ((ret) || !(p_drv->attach)) 402 if (ret)
393 put_device(dev); 403 put_device(dev);
394 return (ret); 404 return (ret);
395} 405}
@@ -399,24 +409,66 @@ static int pcmcia_device_remove(struct device * dev)
399{ 409{
400 struct pcmcia_device *p_dev; 410 struct pcmcia_device *p_dev;
401 struct pcmcia_driver *p_drv; 411 struct pcmcia_driver *p_drv;
412 int i;
402 413
403 /* detach the "instance" */ 414 /* detach the "instance" */
404 p_dev = to_pcmcia_dev(dev); 415 p_dev = to_pcmcia_dev(dev);
405 p_drv = to_pcmcia_drv(dev->driver); 416 p_drv = to_pcmcia_drv(dev->driver);
417 if (!p_drv)
418 return 0;
406 419
407 if (p_drv) { 420 if (p_drv->remove)
408 if ((p_drv->detach) && (p_dev->instance)) { 421 p_drv->remove(p_dev);
409 p_drv->detach(p_dev->instance); 422
410 /* from pcmcia_probe_device */ 423 /* check for proper unloading */
411 put_device(&p_dev->dev); 424 if (p_dev->state & (CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED))
412 } 425 printk(KERN_INFO "pcmcia: driver %s did not release config properly\n",
413 module_put(p_drv->owner); 426 p_drv->drv.name);
414 } 427
428 for (i = 0; i < MAX_WIN; i++)
429 if (p_dev->state & CLIENT_WIN_REQ(i))
430 printk(KERN_INFO "pcmcia: driver %s did not release windows properly\n",
431 p_drv->drv.name);
432
433 /* references from pcmcia_probe_device */
434 p_dev->state = CLIENT_UNBOUND;
435 pcmcia_put_dev(p_dev);
436 module_put(p_drv->owner);
415 437
416 return 0; 438 return 0;
417} 439}
418 440
419 441
442/*
443 * Removes a PCMCIA card from the device tree and socket list.
444 */
445static void pcmcia_card_remove(struct pcmcia_socket *s)
446{
447 struct pcmcia_device *p_dev;
448 unsigned long flags;
449
450 ds_dbg(2, "unbind_request(%d)\n", s->sock);
451
452 s->device_count = 0;
453
454 for (;;) {
455 /* unregister all pcmcia_devices registered with this socket*/
456 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
457 if (list_empty(&s->devices_list)) {
458 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
459 return;
460 }
461 p_dev = list_entry((&s->devices_list)->next, struct pcmcia_device, socket_device_list);
462 list_del(&p_dev->socket_device_list);
463 p_dev->state |= CLIENT_STALE;
464 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
465
466 device_unregister(&p_dev->dev);
467 }
468
469 return;
470} /* unbind_request */
471
420 472
421/* 473/*
422 * pcmcia_device_query -- determine information about a pcmcia device 474 * pcmcia_device_query -- determine information about a pcmcia device
@@ -517,10 +569,9 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
517 if (s->device_count == 2) 569 if (s->device_count == 2)
518 goto err_put; 570 goto err_put;
519 571
520 p_dev = kmalloc(sizeof(struct pcmcia_device), GFP_KERNEL); 572 p_dev = kzalloc(sizeof(struct pcmcia_device), GFP_KERNEL);
521 if (!p_dev) 573 if (!p_dev)
522 goto err_put; 574 goto err_put;
523 memset(p_dev, 0, sizeof(struct pcmcia_device));
524 575
525 p_dev->socket = s; 576 p_dev->socket = s;
526 p_dev->device_no = (s->device_count++); 577 p_dev->device_no = (s->device_count++);
@@ -583,7 +634,9 @@ static int pcmcia_card_add(struct pcmcia_socket *s)
583 if (!(s->resource_setup_done)) 634 if (!(s->resource_setup_done))
584 return -EAGAIN; /* try again, but later... */ 635 return -EAGAIN; /* try again, but later... */
585 636
586 pcmcia_validate_mem(s); 637 if (pcmcia_validate_mem(s))
638 return -EAGAIN; /* try again, but later... */
639
587 ret = pccard_validate_cis(s, BIND_FN_ALL, &cisinfo); 640 ret = pccard_validate_cis(s, BIND_FN_ALL, &cisinfo);
588 if (ret || !cisinfo.Chains) { 641 if (ret || !cisinfo.Chains) {
589 ds_dbg(0, "invalid CIS or invalid resources\n"); 642 ds_dbg(0, "invalid CIS or invalid resources\n");
@@ -918,55 +971,84 @@ static struct device_attribute pcmcia_dev_attrs[] = {
918 __ATTR_NULL, 971 __ATTR_NULL,
919}; 972};
920 973
974/* PM support, also needed for reset */
921 975
922/*====================================================================== 976static int pcmcia_dev_suspend(struct device * dev, pm_message_t state)
977{
978 struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
979 struct pcmcia_driver *p_drv = NULL;
923 980
924 The card status event handler. 981 if (dev->driver)
925 982 p_drv = to_pcmcia_drv(dev->driver);
926======================================================================*/
927 983
928struct send_event_data { 984 if (p_drv && p_drv->suspend)
929 struct pcmcia_socket *skt; 985 return p_drv->suspend(p_dev);
930 event_t event; 986
931 int priority; 987 return 0;
932}; 988}
933 989
934static int send_event_callback(struct device *dev, void * _data) 990
991static int pcmcia_dev_resume(struct device * dev)
935{ 992{
936 struct pcmcia_device *p_dev = to_pcmcia_dev(dev); 993 struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
937 struct pcmcia_driver *p_drv; 994 struct pcmcia_driver *p_drv = NULL;
938 struct send_event_data *data = _data;
939 995
940 /* we get called for all sockets, but may only pass the event 996 if (dev->driver)
941 * for drivers _on the affected socket_ */ 997 p_drv = to_pcmcia_drv(dev->driver);
942 if (p_dev->socket != data->skt)
943 return 0;
944 998
945 p_drv = to_pcmcia_drv(p_dev->dev.driver); 999 if (p_drv && p_drv->resume)
946 if (!p_drv) 1000 return p_drv->resume(p_dev);
1001
1002 return 0;
1003}
1004
1005
1006static int pcmcia_bus_suspend_callback(struct device *dev, void * _data)
1007{
1008 struct pcmcia_socket *skt = _data;
1009 struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
1010
1011 if (p_dev->socket != skt)
947 return 0; 1012 return 0;
948 1013
949 if (p_dev->state & (CLIENT_UNBOUND|CLIENT_STALE)) 1014 return dpm_runtime_suspend(dev, PMSG_SUSPEND);
1015}
1016
1017static int pcmcia_bus_resume_callback(struct device *dev, void * _data)
1018{
1019 struct pcmcia_socket *skt = _data;
1020 struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
1021
1022 if (p_dev->socket != skt)
950 return 0; 1023 return 0;
951 1024
952 if (p_drv->event) 1025 dpm_runtime_resume(dev);
953 return p_drv->event(data->event, data->priority,
954 &p_dev->event_callback_args);
955 1026
956 return 0; 1027 return 0;
957} 1028}
958 1029
959static int send_event(struct pcmcia_socket *s, event_t event, int priority) 1030static int pcmcia_bus_resume(struct pcmcia_socket *skt)
960{ 1031{
961 struct send_event_data private; 1032 bus_for_each_dev(&pcmcia_bus_type, NULL, skt, pcmcia_bus_resume_callback);
1033 return 0;
1034}
1035
1036static int pcmcia_bus_suspend(struct pcmcia_socket *skt)
1037{
1038 if (bus_for_each_dev(&pcmcia_bus_type, NULL, skt,
1039 pcmcia_bus_suspend_callback)) {
1040 pcmcia_bus_resume(skt);
1041 return -EIO;
1042 }
1043 return 0;
1044}
962 1045
963 private.skt = s;
964 private.event = event;
965 private.priority = priority;
966 1046
967 return bus_for_each_dev(&pcmcia_bus_type, NULL, &private, send_event_callback); 1047/*======================================================================
968} /* send_event */
969 1048
1049 The card status event handler.
1050
1051======================================================================*/
970 1052
971/* Normally, the event is passed to individual drivers after 1053/* Normally, the event is passed to individual drivers after
972 * informing userspace. Only for CS_EVENT_CARD_REMOVAL this 1054 * informing userspace. Only for CS_EVENT_CARD_REMOVAL this
@@ -976,20 +1058,17 @@ static int send_event(struct pcmcia_socket *s, event_t event, int priority)
976static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) 1058static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
977{ 1059{
978 struct pcmcia_socket *s = pcmcia_get_socket(skt); 1060 struct pcmcia_socket *s = pcmcia_get_socket(skt);
979 int ret = 0;
980 1061
981 ds_dbg(1, "ds_event(0x%06x, %d, 0x%p)\n", 1062 ds_dbg(1, "ds_event(0x%06x, %d, 0x%p)\n",
982 event, priority, skt); 1063 event, priority, skt);
983
984 switch (event) {
985 1064
1065 switch (event) {
986 case CS_EVENT_CARD_REMOVAL: 1066 case CS_EVENT_CARD_REMOVAL:
987 s->pcmcia_state.present = 0; 1067 s->pcmcia_state.present = 0;
988 send_event(skt, event, priority); 1068 pcmcia_card_remove(skt);
989 unbind_request(skt);
990 handle_event(skt, event); 1069 handle_event(skt, event);
991 break; 1070 break;
992 1071
993 case CS_EVENT_CARD_INSERTION: 1072 case CS_EVENT_CARD_INSERTION:
994 s->pcmcia_state.present = 1; 1073 s->pcmcia_state.present = 1;
995 pcmcia_card_add(skt); 1074 pcmcia_card_add(skt);
@@ -997,12 +1076,14 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
997 break; 1076 break;
998 1077
999 case CS_EVENT_EJECTION_REQUEST: 1078 case CS_EVENT_EJECTION_REQUEST:
1000 ret = send_event(skt, event, priority);
1001 break; 1079 break;
1002 1080
1081 case CS_EVENT_PM_SUSPEND:
1082 case CS_EVENT_PM_RESUME:
1083 case CS_EVENT_RESET_PHYSICAL:
1084 case CS_EVENT_CARD_RESET:
1003 default: 1085 default:
1004 handle_event(skt, event); 1086 handle_event(skt, event);
1005 send_event(skt, event, priority);
1006 break; 1087 break;
1007 } 1088 }
1008 1089
@@ -1012,152 +1093,12 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
1012} /* ds_event */ 1093} /* ds_event */
1013 1094
1014 1095
1015
1016int pcmcia_register_client(struct pcmcia_device **handle, client_reg_t *req)
1017{
1018 struct pcmcia_socket *s = NULL;
1019 struct pcmcia_device *p_dev = NULL;
1020 struct pcmcia_driver *p_drv = NULL;
1021
1022 /* Look for unbound client with matching dev_info */
1023 down_read(&pcmcia_socket_list_rwsem);
1024 list_for_each_entry(s, &pcmcia_socket_list, socket_list) {
1025 unsigned long flags;
1026
1027 if (s->state & SOCKET_CARDBUS)
1028 continue;
1029
1030 s = pcmcia_get_socket(s);
1031 if (!s)
1032 continue;
1033 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
1034 list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
1035 p_dev = pcmcia_get_dev(p_dev);
1036 if (!p_dev)
1037 continue;
1038 if (!(p_dev->state & CLIENT_UNBOUND) ||
1039 (!p_dev->dev.driver)) {
1040 pcmcia_put_dev(p_dev);
1041 continue;
1042 }
1043 p_drv = to_pcmcia_drv(p_dev->dev.driver);
1044 if (!strncmp(p_drv->drv.name, (char *)req->dev_info, DEV_NAME_LEN)) {
1045 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
1046 goto found;
1047 }
1048 pcmcia_put_dev(p_dev);
1049 }
1050 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
1051 pcmcia_put_socket(s);
1052 }
1053 found:
1054 up_read(&pcmcia_socket_list_rwsem);
1055 if (!p_dev)
1056 return -ENODEV;
1057
1058 pcmcia_put_socket(s); /* safe, as we already hold a reference from bind_device */
1059
1060 *handle = p_dev;
1061 p_dev->state &= ~CLIENT_UNBOUND;
1062 p_dev->event_callback_args = req->event_callback_args;
1063 p_dev->event_callback_args.client_handle = p_dev;
1064
1065
1066 if (!s->functions) {
1067 cistpl_longlink_mfc_t mfc;
1068 if (pccard_read_tuple(s, p_dev->func, CISTPL_LONGLINK_MFC, &mfc)
1069 == CS_SUCCESS)
1070 s->functions = mfc.nfn;
1071 else
1072 s->functions = 1;
1073 s->config = kmalloc(sizeof(config_t) * s->functions,
1074 GFP_KERNEL);
1075 if (!s->config)
1076 goto out_no_resource;
1077 memset(s->config, 0, sizeof(config_t) * s->functions);
1078 }
1079
1080 ds_dbg(1, "register_client(): client 0x%p, dev %s\n",
1081 p_dev, p_dev->dev.bus_id);
1082
1083 if ((s->state & (SOCKET_PRESENT|SOCKET_CARDBUS)) == SOCKET_PRESENT) {
1084 if (p_drv->event)
1085 p_drv->event(CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW,
1086 &p_dev->event_callback_args);
1087
1088 }
1089
1090 return CS_SUCCESS;
1091
1092 out_no_resource:
1093 pcmcia_put_dev(p_dev);
1094 return CS_OUT_OF_RESOURCE;
1095} /* register_client */
1096EXPORT_SYMBOL(pcmcia_register_client);
1097
1098
1099/* unbind _all_ devices attached to a given pcmcia_bus_socket. The
1100 * drivers have been called with EVENT_CARD_REMOVAL before.
1101 */
1102static int unbind_request(struct pcmcia_socket *s)
1103{
1104 struct pcmcia_device *p_dev;
1105 unsigned long flags;
1106
1107 ds_dbg(2, "unbind_request(%d)\n", s->sock);
1108
1109 s->device_count = 0;
1110
1111 for (;;) {
1112 /* unregister all pcmcia_devices registered with this socket*/
1113 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
1114 if (list_empty(&s->devices_list)) {
1115 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
1116 return 0;
1117 }
1118 p_dev = list_entry((&s->devices_list)->next, struct pcmcia_device, socket_device_list);
1119 list_del(&p_dev->socket_device_list);
1120 p_dev->state |= CLIENT_STALE;
1121 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
1122
1123 device_unregister(&p_dev->dev);
1124 }
1125
1126 return 0;
1127} /* unbind_request */
1128
1129int pcmcia_deregister_client(struct pcmcia_device *p_dev)
1130{
1131 struct pcmcia_socket *s;
1132 int i;
1133
1134 s = p_dev->socket;
1135 ds_dbg(1, "deregister_client(%p)\n", p_dev);
1136
1137 if (p_dev->state & (CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED))
1138 goto warn_out;
1139 for (i = 0; i < MAX_WIN; i++)
1140 if (p_dev->state & CLIENT_WIN_REQ(i))
1141 goto warn_out;
1142
1143 if (p_dev->state & CLIENT_STALE) {
1144 p_dev->state &= ~CLIENT_STALE;
1145 pcmcia_put_dev(p_dev);
1146 } else {
1147 p_dev->state = CLIENT_UNBOUND;
1148 }
1149
1150 return CS_SUCCESS;
1151 warn_out:
1152 printk(KERN_WARNING "ds: deregister_client was called too early.\n");
1153 return CS_IN_USE;
1154} /* deregister_client */
1155EXPORT_SYMBOL(pcmcia_deregister_client);
1156
1157static struct pcmcia_callback pcmcia_bus_callback = { 1096static struct pcmcia_callback pcmcia_bus_callback = {
1158 .owner = THIS_MODULE, 1097 .owner = THIS_MODULE,
1159 .event = ds_event, 1098 .event = ds_event,
1160 .requery = pcmcia_bus_rescan, 1099 .requery = pcmcia_bus_rescan,
1100 .suspend = pcmcia_bus_suspend,
1101 .resume = pcmcia_bus_resume,
1161}; 1102};
1162 1103
1163static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev, 1104static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev,
@@ -1226,6 +1167,8 @@ struct bus_type pcmcia_bus_type = {
1226 .uevent = pcmcia_bus_uevent, 1167 .uevent = pcmcia_bus_uevent,
1227 .match = pcmcia_bus_match, 1168 .match = pcmcia_bus_match,
1228 .dev_attrs = pcmcia_dev_attrs, 1169 .dev_attrs = pcmcia_dev_attrs,
1170 .suspend = pcmcia_dev_suspend,
1171 .resume = pcmcia_dev_resume,
1229}; 1172};
1230 1173
1231 1174
diff --git a/drivers/pcmcia/hd64465_ss.c b/drivers/pcmcia/hd64465_ss.c
index 561706ba4499..b39435bbfaeb 100644
--- a/drivers/pcmcia/hd64465_ss.c
+++ b/drivers/pcmcia/hd64465_ss.c
@@ -417,18 +417,6 @@ static int hs_get_status(struct pcmcia_socket *s, u_int *value)
417 417
418/*============================================================*/ 418/*============================================================*/
419 419
420static int hs_get_socket(struct pcmcia_socket *s, socket_state_t *state)
421{
422 hs_socket_t *sp = container_of(s, struct hs_socket_t, socket);
423
424 DPRINTK("hs_get_socket(%d)\n", sock);
425
426 *state = sp->state;
427 return 0;
428}
429
430/*============================================================*/
431
432static int hs_set_socket(struct pcmcia_socket *s, socket_state_t *state) 420static int hs_set_socket(struct pcmcia_socket *s, socket_state_t *state)
433{ 421{
434 hs_socket_t *sp = container_of(s, struct hs_socket_t, socket); 422 hs_socket_t *sp = container_of(s, struct hs_socket_t, socket);
@@ -749,7 +737,6 @@ static irqreturn_t hs_interrupt(int irq, void *dev, struct pt_regs *regs)
749static struct pccard_operations hs_operations = { 737static struct pccard_operations hs_operations = {
750 .init = hs_init, 738 .init = hs_init,
751 .get_status = hs_get_status, 739 .get_status = hs_get_status,
752 .get_socket = hs_get_socket,
753 .set_socket = hs_set_socket, 740 .set_socket = hs_set_socket,
754 .set_io_map = hs_set_io_map, 741 .set_io_map = hs_set_io_map,
755 .set_mem_map = hs_set_mem_map, 742 .set_mem_map = hs_set_mem_map,
diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c
index f3fdc748659d..7979c85df3dc 100644
--- a/drivers/pcmcia/i82092.c
+++ b/drivers/pcmcia/i82092.c
@@ -66,7 +66,6 @@ static struct pci_driver i82092aa_pci_drv = {
66static struct pccard_operations i82092aa_operations = { 66static struct pccard_operations i82092aa_operations = {
67 .init = i82092aa_init, 67 .init = i82092aa_init,
68 .get_status = i82092aa_get_status, 68 .get_status = i82092aa_get_status,
69 .get_socket = i82092aa_get_socket,
70 .set_socket = i82092aa_set_socket, 69 .set_socket = i82092aa_set_socket,
71 .set_io_map = i82092aa_set_io_map, 70 .set_io_map = i82092aa_set_io_map,
72 .set_mem_map = i82092aa_set_mem_map, 71 .set_mem_map = i82092aa_set_mem_map,
@@ -482,78 +481,6 @@ static int i82092aa_get_status(struct pcmcia_socket *socket, u_int *value)
482} 481}
483 482
484 483
485static int i82092aa_get_socket(struct pcmcia_socket *socket, socket_state_t *state)
486{
487 unsigned int sock = container_of(socket, struct socket_info, socket)->number;
488 unsigned char reg,vcc,vpp;
489
490 enter("i82092aa_get_socket");
491 state->flags = 0;
492 state->Vcc = 0;
493 state->Vpp = 0;
494 state->io_irq = 0;
495 state->csc_mask = 0;
496
497 /* First the power status of the socket */
498 reg = indirect_read(sock,I365_POWER); /* PCTRL - Power Control Register */
499
500 if (reg & I365_PWR_AUTO)
501 state->flags |= SS_PWR_AUTO; /* Automatic Power Switch */
502
503 if (reg & I365_PWR_OUT)
504 state->flags |= SS_OUTPUT_ENA; /* Output signals are enabled */
505
506 vcc = reg & I365_VCC_MASK; vpp = reg & I365_VPP1_MASK;
507
508 if (reg & I365_VCC_5V) { /* Can still be 3.3V, in this case the Vcc value will be overwritten later */
509 state->Vcc = 50;
510
511 if (vpp == I365_VPP1_5V)
512 state->Vpp = 50;
513 if (vpp == I365_VPP1_12V)
514 state->Vpp = 120;
515
516 }
517
518 if ((reg & I365_VCC_3V)==I365_VCC_3V)
519 state->Vcc = 33;
520
521
522 /* Now the IO card, RESET flags and IO interrupt */
523
524 reg = indirect_read(sock, I365_INTCTL); /* IGENC, Interrupt and General Control */
525
526 if ((reg & I365_PC_RESET)==0)
527 state->flags |= SS_RESET;
528 if (reg & I365_PC_IOCARD)
529 state->flags |= SS_IOCARD; /* This is an IO card */
530
531 /* Set the IRQ number */
532 if (sockets[sock].dev!=NULL)
533 state->io_irq = sockets[sock].dev->irq;
534
535 /* Card status change */
536 reg = indirect_read(sock, I365_CSCINT); /* CSCICR, Card Status Change Interrupt Configuration */
537
538 if (reg & I365_CSC_DETECT)
539 state->csc_mask |= SS_DETECT; /* Card detect is enabled */
540
541 if (state->flags & SS_IOCARD) {/* IO Cards behave different */
542 if (reg & I365_CSC_STSCHG)
543 state->csc_mask |= SS_STSCHG;
544 } else {
545 if (reg & I365_CSC_BVD1)
546 state->csc_mask |= SS_BATDEAD;
547 if (reg & I365_CSC_BVD2)
548 state->csc_mask |= SS_BATWARN;
549 if (reg & I365_CSC_READY)
550 state->csc_mask |= SS_READY;
551 }
552
553 leave("i82092aa_get_socket");
554 return 0;
555}
556
557static int i82092aa_set_socket(struct pcmcia_socket *socket, socket_state_t *state) 484static int i82092aa_set_socket(struct pcmcia_socket *socket, socket_state_t *state)
558{ 485{
559 unsigned int sock = container_of(socket, struct socket_info, socket)->number; 486 unsigned int sock = container_of(socket, struct socket_info, socket)->number;
diff --git a/drivers/pcmcia/i82092aa.h b/drivers/pcmcia/i82092aa.h
index b98cac7bda9f..9c14599d0673 100644
--- a/drivers/pcmcia/i82092aa.h
+++ b/drivers/pcmcia/i82092aa.h
@@ -29,7 +29,6 @@ static irqreturn_t i82092aa_interrupt(int irq, void *dev, struct pt_regs *regs);
29 29
30 30
31static int i82092aa_get_status(struct pcmcia_socket *socket, u_int *value); 31static int i82092aa_get_status(struct pcmcia_socket *socket, u_int *value);
32static int i82092aa_get_socket(struct pcmcia_socket *socket, socket_state_t *state);
33static int i82092aa_set_socket(struct pcmcia_socket *socket, socket_state_t *state); 32static int i82092aa_set_socket(struct pcmcia_socket *socket, socket_state_t *state);
34static int i82092aa_set_io_map(struct pcmcia_socket *socket, struct pccard_io_map *io); 33static int i82092aa_set_io_map(struct pcmcia_socket *socket, struct pccard_io_map *io);
35static int i82092aa_set_mem_map(struct pcmcia_socket *socket, struct pccard_mem_map *mem); 34static int i82092aa_set_mem_map(struct pcmcia_socket *socket, struct pccard_mem_map *mem);
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
index 4d56bc9926d6..35a92d1e4945 100644
--- a/drivers/pcmcia/i82365.c
+++ b/drivers/pcmcia/i82365.c
@@ -940,78 +940,6 @@ static int i365_get_status(u_short sock, u_int *value)
940 940
941/*====================================================================*/ 941/*====================================================================*/
942 942
943static int i365_get_socket(u_short sock, socket_state_t *state)
944{
945 struct i82365_socket *t = &socket[sock];
946 u_char reg, vcc, vpp;
947
948 reg = i365_get(sock, I365_POWER);
949 state->flags = (reg & I365_PWR_AUTO) ? SS_PWR_AUTO : 0;
950 state->flags |= (reg & I365_PWR_OUT) ? SS_OUTPUT_ENA : 0;
951 vcc = reg & I365_VCC_MASK; vpp = reg & I365_VPP1_MASK;
952 state->Vcc = state->Vpp = 0;
953 if (t->flags & IS_CIRRUS) {
954 if (i365_get(sock, PD67_MISC_CTL_1) & PD67_MC1_VCC_3V) {
955 if (reg & I365_VCC_5V) state->Vcc = 33;
956 if (vpp == I365_VPP1_5V) state->Vpp = 33;
957 } else {
958 if (reg & I365_VCC_5V) state->Vcc = 50;
959 if (vpp == I365_VPP1_5V) state->Vpp = 50;
960 }
961 if (vpp == I365_VPP1_12V) state->Vpp = 120;
962 } else if (t->flags & IS_VG_PWR) {
963 if (i365_get(sock, VG469_VSELECT) & VG469_VSEL_VCC) {
964 if (reg & I365_VCC_5V) state->Vcc = 33;
965 if (vpp == I365_VPP1_5V) state->Vpp = 33;
966 } else {
967 if (reg & I365_VCC_5V) state->Vcc = 50;
968 if (vpp == I365_VPP1_5V) state->Vpp = 50;
969 }
970 if (vpp == I365_VPP1_12V) state->Vpp = 120;
971 } else if (t->flags & IS_DF_PWR) {
972 if (vcc == I365_VCC_3V) state->Vcc = 33;
973 if (vcc == I365_VCC_5V) state->Vcc = 50;
974 if (vpp == I365_VPP1_5V) state->Vpp = 50;
975 if (vpp == I365_VPP1_12V) state->Vpp = 120;
976 } else {
977 if (reg & I365_VCC_5V) {
978 state->Vcc = 50;
979 if (vpp == I365_VPP1_5V) state->Vpp = 50;
980 if (vpp == I365_VPP1_12V) state->Vpp = 120;
981 }
982 }
983
984 /* IO card, RESET flags, IO interrupt */
985 reg = i365_get(sock, I365_INTCTL);
986 state->flags |= (reg & I365_PC_RESET) ? 0 : SS_RESET;
987 if (reg & I365_PC_IOCARD) state->flags |= SS_IOCARD;
988 state->io_irq = reg & I365_IRQ_MASK;
989
990 /* speaker control */
991 if (t->flags & IS_CIRRUS) {
992 if (i365_get(sock, PD67_MISC_CTL_1) & PD67_MC1_SPKR_ENA)
993 state->flags |= SS_SPKR_ENA;
994 }
995
996 /* Card status change mask */
997 reg = i365_get(sock, I365_CSCINT);
998 state->csc_mask = (reg & I365_CSC_DETECT) ? SS_DETECT : 0;
999 if (state->flags & SS_IOCARD)
1000 state->csc_mask |= (reg & I365_CSC_STSCHG) ? SS_STSCHG : 0;
1001 else {
1002 state->csc_mask |= (reg & I365_CSC_BVD1) ? SS_BATDEAD : 0;
1003 state->csc_mask |= (reg & I365_CSC_BVD2) ? SS_BATWARN : 0;
1004 state->csc_mask |= (reg & I365_CSC_READY) ? SS_READY : 0;
1005 }
1006
1007 debug(1, "GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, "
1008 "io_irq %d, csc_mask %#2.2x\n", sock, state->flags,
1009 state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
1010 return 0;
1011} /* i365_get_socket */
1012
1013/*====================================================================*/
1014
1015static int i365_set_socket(u_short sock, socket_state_t *state) 943static int i365_set_socket(u_short sock, socket_state_t *state)
1016{ 944{
1017 struct i82365_socket *t = &socket[sock]; 945 struct i82365_socket *t = &socket[sock];
@@ -1265,16 +1193,6 @@ static int pcic_get_status(struct pcmcia_socket *s, u_int *value)
1265 LOCKED(i365_get_status(sock, value)); 1193 LOCKED(i365_get_status(sock, value));
1266} 1194}
1267 1195
1268static int pcic_get_socket(struct pcmcia_socket *s, socket_state_t *state)
1269{
1270 unsigned int sock = container_of(s, struct i82365_socket, socket)->number;
1271
1272 if (socket[sock].flags & IS_ALIVE)
1273 return -EINVAL;
1274
1275 LOCKED(i365_get_socket(sock, state));
1276}
1277
1278static int pcic_set_socket(struct pcmcia_socket *s, socket_state_t *state) 1196static int pcic_set_socket(struct pcmcia_socket *s, socket_state_t *state)
1279{ 1197{
1280 unsigned int sock = container_of(s, struct i82365_socket, socket)->number; 1198 unsigned int sock = container_of(s, struct i82365_socket, socket)->number;
@@ -1324,7 +1242,6 @@ static int pcic_init(struct pcmcia_socket *s)
1324static struct pccard_operations pcic_operations = { 1242static struct pccard_operations pcic_operations = {
1325 .init = pcic_init, 1243 .init = pcic_init,
1326 .get_status = pcic_get_status, 1244 .get_status = pcic_get_status,
1327 .get_socket = pcic_get_socket,
1328 .set_socket = pcic_set_socket, 1245 .set_socket = pcic_set_socket,
1329 .set_io_map = pcic_set_io_map, 1246 .set_io_map = pcic_set_io_map,
1330 .set_mem_map = pcic_set_mem_map, 1247 .set_mem_map = pcic_set_mem_map,
diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c
index 078579ae6359..071cf485e1a3 100644
--- a/drivers/pcmcia/m32r_cfc.c
+++ b/drivers/pcmcia/m32r_cfc.c
@@ -480,25 +480,6 @@ static int _pcc_get_status(u_short sock, u_int *value)
480 480
481/*====================================================================*/ 481/*====================================================================*/
482 482
483static int _pcc_get_socket(u_short sock, socket_state_t *state)
484{
485// pcc_socket_t *t = &socket[sock];
486
487 state->flags = 0;
488 state->csc_mask = SS_DETECT;
489 state->csc_mask |= SS_READY;
490 state->io_irq = 0;
491 state->Vcc = 33; /* 3.3V fixed */
492 state->Vpp = 33;
493
494 debug(3, "m32r_cfc: GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, "
495 "io_irq %d, csc_mask %#2.2x\n", sock, state->flags,
496 state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
497 return 0;
498} /* _get_socket */
499
500/*====================================================================*/
501
502static int _pcc_set_socket(u_short sock, socket_state_t *state) 483static int _pcc_set_socket(u_short sock, socket_state_t *state)
503{ 484{
504 debug(3, "m32r_cfc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, " 485 debug(3, "m32r_cfc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
@@ -667,18 +648,6 @@ static int pcc_get_status(struct pcmcia_socket *s, u_int *value)
667 LOCKED(_pcc_get_status(sock, value)); 648 LOCKED(_pcc_get_status(sock, value));
668} 649}
669 650
670static int pcc_get_socket(struct pcmcia_socket *s, socket_state_t *state)
671{
672 unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
673
674 if (socket[sock].flags & IS_ALIVE) {
675 debug(3, "m32r_cfc: pcc_get_socket: sock(%d) -EINVAL\n", sock);
676 return -EINVAL;
677 }
678 debug(3, "m32r_cfc: pcc_get_socket: sock(%d)\n", sock);
679 LOCKED(_pcc_get_socket(sock, state));
680}
681
682static int pcc_set_socket(struct pcmcia_socket *s, socket_state_t *state) 651static int pcc_set_socket(struct pcmcia_socket *s, socket_state_t *state)
683{ 652{
684 unsigned int sock = container_of(s, struct pcc_socket, socket)->number; 653 unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
@@ -724,7 +693,6 @@ static int pcc_init(struct pcmcia_socket *s)
724static struct pccard_operations pcc_operations = { 693static struct pccard_operations pcc_operations = {
725 .init = pcc_init, 694 .init = pcc_init,
726 .get_status = pcc_get_status, 695 .get_status = pcc_get_status,
727 .get_socket = pcc_get_socket,
728 .set_socket = pcc_set_socket, 696 .set_socket = pcc_set_socket,
729 .set_io_map = pcc_set_io_map, 697 .set_io_map = pcc_set_io_map,
730 .set_mem_map = pcc_set_mem_map, 698 .set_mem_map = pcc_set_mem_map,
diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c
index 356a6fb416a1..70d5f0748d55 100644
--- a/drivers/pcmcia/m32r_pcc.c
+++ b/drivers/pcmcia/m32r_pcc.c
@@ -429,16 +429,6 @@ static int _pcc_get_status(u_short sock, u_int *value)
429 429
430/*====================================================================*/ 430/*====================================================================*/
431 431
432static int _pcc_get_socket(u_short sock, socket_state_t *state)
433{
434 debug(3, "m32r-pcc: GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, "
435 "io_irq %d, csc_mask %#2.2x\n", sock, state->flags,
436 state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
437 return 0;
438} /* _get_socket */
439
440/*====================================================================*/
441
442static int _pcc_set_socket(u_short sock, socket_state_t *state) 432static int _pcc_set_socket(u_short sock, socket_state_t *state)
443{ 433{
444 u_long reg = 0; 434 u_long reg = 0;
@@ -641,15 +631,6 @@ static int pcc_get_status(struct pcmcia_socket *s, u_int *value)
641 LOCKED(_pcc_get_status(sock, value)); 631 LOCKED(_pcc_get_status(sock, value));
642} 632}
643 633
644static int pcc_get_socket(struct pcmcia_socket *s, socket_state_t *state)
645{
646 unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
647
648 if (socket[sock].flags & IS_ALIVE)
649 return -EINVAL;
650 LOCKED(_pcc_get_socket(sock, state));
651}
652
653static int pcc_set_socket(struct pcmcia_socket *s, socket_state_t *state) 634static int pcc_set_socket(struct pcmcia_socket *s, socket_state_t *state)
654{ 635{
655 unsigned int sock = container_of(s, struct pcc_socket, socket)->number; 636 unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
@@ -687,7 +668,6 @@ static int pcc_init(struct pcmcia_socket *s)
687static struct pccard_operations pcc_operations = { 668static struct pccard_operations pcc_operations = {
688 .init = pcc_init, 669 .init = pcc_init,
689 .get_status = pcc_get_status, 670 .get_status = pcc_get_status,
690 .get_socket = pcc_get_socket,
691 .set_socket = pcc_set_socket, 671 .set_socket = pcc_set_socket,
692 .set_io_map = pcc_set_io_map, 672 .set_io_map = pcc_set_io_map,
693 .set_mem_map = pcc_set_mem_map, 673 .set_mem_map = pcc_set_mem_map,
diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c
index 6d9f71cfcb34..0e07d9535116 100644
--- a/drivers/pcmcia/m8xx_pcmcia.c
+++ b/drivers/pcmcia/m8xx_pcmcia.c
@@ -9,6 +9,9 @@
9 * <oliver.kurth@cyclades.de> 9 * <oliver.kurth@cyclades.de>
10 * Further fixes, v2.6 kernel port 10 * Further fixes, v2.6 kernel port
11 * <marcelo.tosatti@cyclades.com> 11 * <marcelo.tosatti@cyclades.com>
12 *
13 * Some fixes, additions (C) 2005 Montavista Software, Inc.
14 * <vbordug@ru.mvista.com>
12 * 15 *
13 * "The ExCA standard specifies that socket controllers should provide 16 * "The ExCA standard specifies that socket controllers should provide
14 * two IO and five memory windows per socket, which can be independently 17 * two IO and five memory windows per socket, which can be independently
@@ -97,6 +100,11 @@ MODULE_LICENSE("Dual MPL/GPL");
97#endif 100#endif
98#endif 101#endif
99 102
103#if defined(CONFIG_MPC885ADS)
104#define CONFIG_PCMCIA_SLOT_A
105#define PCMCIA_GLITCHY_CD
106#endif
107
100/* Cyclades ACS uses both slots */ 108/* Cyclades ACS uses both slots */
101#ifdef CONFIG_PRxK 109#ifdef CONFIG_PRxK
102#define CONFIG_PCMCIA_SLOT_A 110#define CONFIG_PCMCIA_SLOT_A
@@ -374,10 +382,10 @@ static int voltage_set(int slot, int vcc, int vpp)
374 } 382 }
375 383
376 /* first, turn off all power */ 384 /* first, turn off all power */
377 out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) & ~(BCSR1_PCCVCC_MASK | BCSR1_PCCVPP_MASK)); 385 out_be32((u32 *)BCSR1, in_be32((u32 *)BCSR1) & ~(BCSR1_PCCVCC_MASK | BCSR1_PCCVPP_MASK));
378 386
379 /* enable new powersettings */ 387 /* enable new powersettings */
380 out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) | reg); 388 out_be32((u32 *)BCSR1, in_be32((u32 *)BCSR1) | reg);
381 389
382 return 0; 390 return 0;
383} 391}
@@ -386,12 +394,89 @@ static int voltage_set(int slot, int vcc, int vpp)
386 394
387static void hardware_enable(int slot) 395static void hardware_enable(int slot)
388{ 396{
389 out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) & ~BCSR1_PCCEN); 397 out_be32((u32 *)BCSR1, in_be32((u32 *)BCSR1) & ~BCSR1_PCCEN);
390} 398}
391 399
392static void hardware_disable(int slot) 400static void hardware_disable(int slot)
393{ 401{
394 out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) | BCSR1_PCCEN); 402 out_be32((u32 *)BCSR1, in_be32((u32 *)BCSR1) | BCSR1_PCCEN);
403}
404
405#endif
406
407/* MPC885ADS Boards */
408
409#if defined(CONFIG_MPC885ADS)
410
411#define PCMCIA_BOARD_MSG "MPC885ADS"
412
413static int voltage_set(int slot, int vcc, int vpp)
414{
415 u32 reg = 0;
416 unsigned *bcsr_io;
417
418 bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
419
420 switch(vcc) {
421 case 0:
422 break;
423 case 33:
424 reg |= BCSR1_PCCVCC0;
425 break;
426 case 50:
427 reg |= BCSR1_PCCVCC1;
428 break;
429 default:
430 return 1;
431 }
432
433 switch(vpp) {
434 case 0:
435 break;
436 case 33:
437 case 50:
438 if(vcc == vpp)
439 reg |= BCSR1_PCCVPP1;
440 else
441 return 1;
442 break;
443 case 120:
444 if ((vcc == 33) || (vcc == 50))
445 reg |= BCSR1_PCCVPP0;
446 else
447 return 1;
448 default:
449 return 1;
450 }
451
452 /* first, turn off all power */
453 out_be32(bcsr_io, in_be32(bcsr_io) & ~(BCSR1_PCCVCC_MASK | BCSR1_PCCVPP_MASK));
454
455 /* enable new powersettings */
456 out_be32(bcsr_io, in_be32(bcsr_io) | reg);
457
458 iounmap(bcsr_io);
459 return 0;
460}
461
462#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
463
464static void hardware_enable(int slot)
465{
466 unsigned *bcsr_io;
467
468 bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
469 out_be32(bcsr_io, in_be32(bcsr_io) & ~BCSR1_PCCEN);
470 iounmap(bcsr_io);
471}
472
473static void hardware_disable(int slot)
474{
475 unsigned *bcsr_io;
476
477 bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
478 out_be32(bcsr_io, in_be32(bcsr_io) | BCSR1_PCCEN);
479 iounmap(bcsr_io);
395} 480}
396 481
397#endif 482#endif
@@ -440,10 +525,10 @@ static int voltage_set(int slot, int vcc, int vpp)
440 } 525 }
441 526
442 /* first, turn off all power */ 527 /* first, turn off all power */
443 out_8(&((u8 *)MBX_CSR2_ADDR), in_8(&((u8 *)MBX_CSR2_ADDR)) & ~(CSR2_VCC_MASK | CSR2_VPP_MASK)); 528 out_8((u8 *)MBX_CSR2_ADDR, in_8((u8 *)MBX_CSR2_ADDR) & ~(CSR2_VCC_MASK | CSR2_VPP_MASK));
444 529
445 /* enable new powersettings */ 530 /* enable new powersettings */
446 out_8(&((u8 *)MBX_CSR2_ADDR), in_8(&((u8 *)MBX_CSR2_ADDR)) | reg); 531 out_8((u8 *)MBX_CSR2_ADDR, in_8((u8 *)MBX_CSR2_ADDR) | reg);
447 532
448 return 0; 533 return 0;
449} 534}
@@ -823,17 +908,6 @@ static int m8xx_get_status(struct pcmcia_socket *sock, unsigned int *value)
823 return 0; 908 return 0;
824} 909}
825 910
826static int m8xx_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
827{
828 int lsock = container_of(sock, struct socket_info, socket)->slot;
829 *state = socket[lsock].state; /* copy the whole structure */
830
831 dprintk("GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, "
832 "io_irq %d, csc_mask %#2.2x\n", lsock, state->flags,
833 state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
834 return 0;
835}
836
837static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t *state) 911static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
838{ 912{
839 int lsock = container_of(sock, struct socket_info, socket)->slot; 913 int lsock = container_of(sock, struct socket_info, socket)->slot;
@@ -1023,8 +1097,7 @@ static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
1023 if(io->flags & MAP_WRPROT) 1097 if(io->flags & MAP_WRPROT)
1024 reg |= M8XX_PCMCIA_POR_WRPROT; 1098 reg |= M8XX_PCMCIA_POR_WRPROT;
1025 1099
1026 /*if(io->flags & (MAP_16BIT | MAP_AUTOSZ))*/ 1100 if(io->flags & (MAP_16BIT | MAP_AUTOSZ))
1027 if(io->flags & MAP_16BIT)
1028 reg |= M8XX_PCMCIA_POR_16BIT; 1101 reg |= M8XX_PCMCIA_POR_16BIT;
1029 1102
1030 if(io->flags & MAP_ACTIVE) 1103 if(io->flags & MAP_ACTIVE)
@@ -1169,7 +1242,6 @@ static struct pccard_operations m8xx_services = {
1169 .init = m8xx_sock_init, 1242 .init = m8xx_sock_init,
1170 .suspend = m8xx_suspend, 1243 .suspend = m8xx_suspend,
1171 .get_status = m8xx_get_status, 1244 .get_status = m8xx_get_status,
1172 .get_socket = m8xx_get_socket,
1173 .set_socket = m8xx_set_socket, 1245 .set_socket = m8xx_set_socket,
1174 .set_io_map = m8xx_set_io_map, 1246 .set_io_map = m8xx_set_io_map,
1175 .set_mem_map = m8xx_set_mem_map, 1247 .set_mem_map = m8xx_set_mem_map,
@@ -1244,7 +1316,7 @@ static int __init m8xx_init(void)
1244 socket[i].socket.io_offset = 0; 1316 socket[i].socket.io_offset = 0;
1245 socket[i].socket.pci_irq = i ? 7 : 9; 1317 socket[i].socket.pci_irq = i ? 7 : 9;
1246 socket[i].socket.ops = &m8xx_services; 1318 socket[i].socket.ops = &m8xx_services;
1247 socket[i].socket.resource_ops = &pccard_nonstatic_ops; 1319 socket[i].socket.resource_ops = &pccard_iodyn_ops;
1248 socket[i].socket.cb_dev = NULL; 1320 socket[i].socket.cb_dev = NULL;
1249 socket[i].socket.dev.dev = &m8xx_device.dev; 1321 socket[i].socket.dev.dev = &m8xx_device.dev;
1250 } 1322 }
diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c
index 20642f0e7bfe..f2789afb22b2 100644
--- a/drivers/pcmcia/pd6729.c
+++ b/drivers/pcmcia/pd6729.c
@@ -304,75 +304,6 @@ static int pd6729_get_status(struct pcmcia_socket *sock, u_int *value)
304} 304}
305 305
306 306
307static int pd6729_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
308{
309 struct pd6729_socket *socket
310 = container_of(sock, struct pd6729_socket, socket);
311 unsigned char reg, vcc, vpp;
312
313 state->flags = 0;
314 state->Vcc = 0;
315 state->Vpp = 0;
316 state->io_irq = 0;
317 state->csc_mask = 0;
318
319 /* First the power status of the socket */
320 reg = indirect_read(socket, I365_POWER);
321
322 if (reg & I365_PWR_AUTO)
323 state->flags |= SS_PWR_AUTO; /* Automatic Power Switch */
324
325 if (reg & I365_PWR_OUT)
326 state->flags |= SS_OUTPUT_ENA; /* Output signals are enabled */
327
328 vcc = reg & I365_VCC_MASK; vpp = reg & I365_VPP1_MASK;
329
330 if (reg & I365_VCC_5V) {
331 state->Vcc = (indirect_read(socket, PD67_MISC_CTL_1) &
332 PD67_MC1_VCC_3V) ? 33 : 50;
333
334 if (vpp == I365_VPP1_5V) {
335 if (state->Vcc == 50)
336 state->Vpp = 50;
337 else
338 state->Vpp = 33;
339 }
340 if (vpp == I365_VPP1_12V)
341 state->Vpp = 120;
342 }
343
344 /* Now the IO card, RESET flags and IO interrupt */
345 reg = indirect_read(socket, I365_INTCTL);
346
347 if ((reg & I365_PC_RESET) == 0)
348 state->flags |= SS_RESET;
349 if (reg & I365_PC_IOCARD)
350 state->flags |= SS_IOCARD; /* This is an IO card */
351
352 /* Set the IRQ number */
353 state->io_irq = socket->card_irq;
354
355 /* Card status change */
356 reg = indirect_read(socket, I365_CSCINT);
357
358 if (reg & I365_CSC_DETECT)
359 state->csc_mask |= SS_DETECT; /* Card detect is enabled */
360
361 if (state->flags & SS_IOCARD) {/* IO Cards behave different */
362 if (reg & I365_CSC_STSCHG)
363 state->csc_mask |= SS_STSCHG;
364 } else {
365 if (reg & I365_CSC_BVD1)
366 state->csc_mask |= SS_BATDEAD;
367 if (reg & I365_CSC_BVD2)
368 state->csc_mask |= SS_BATWARN;
369 if (reg & I365_CSC_READY)
370 state->csc_mask |= SS_READY;
371 }
372
373 return 0;
374}
375
376static int pd6729_set_socket(struct pcmcia_socket *sock, socket_state_t *state) 307static int pd6729_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
377{ 308{
378 struct pd6729_socket *socket 309 struct pd6729_socket *socket
@@ -640,7 +571,6 @@ static int pd6729_init(struct pcmcia_socket *sock)
640static struct pccard_operations pd6729_operations = { 571static struct pccard_operations pd6729_operations = {
641 .init = pd6729_init, 572 .init = pd6729_init,
642 .get_status = pd6729_get_status, 573 .get_status = pd6729_get_status,
643 .get_socket = pd6729_get_socket,
644 .set_socket = pd6729_set_socket, 574 .set_socket = pd6729_set_socket,
645 .set_io_map = pd6729_set_io_map, 575 .set_io_map = pd6729_set_io_map,
646 .set_mem_map = pd6729_set_mem_map, 576 .set_mem_map = pd6729_set_mem_map,
@@ -704,13 +634,11 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,
704 char configbyte; 634 char configbyte;
705 struct pd6729_socket *socket; 635 struct pd6729_socket *socket;
706 636
707 socket = kmalloc(sizeof(struct pd6729_socket) * MAX_SOCKETS, 637 socket = kzalloc(sizeof(struct pd6729_socket) * MAX_SOCKETS,
708 GFP_KERNEL); 638 GFP_KERNEL);
709 if (!socket) 639 if (!socket)
710 return -ENOMEM; 640 return -ENOMEM;
711 641
712 memset(socket, 0, sizeof(struct pd6729_socket) * MAX_SOCKETS);
713
714 if ((ret = pci_enable_device(dev))) 642 if ((ret = pci_enable_device(dev)))
715 goto err_out_free_mem; 643 goto err_out_free_mem;
716 644
diff --git a/drivers/pcmcia/pxa2xx_mainstone.c b/drivers/pcmcia/pxa2xx_mainstone.c
index 5209d8c7764f..5d957dfe23d9 100644
--- a/drivers/pcmcia/pxa2xx_mainstone.c
+++ b/drivers/pcmcia/pxa2xx_mainstone.c
@@ -171,10 +171,9 @@ static int __init mst_pcmcia_init(void)
171{ 171{
172 int ret; 172 int ret;
173 173
174 mst_pcmcia_device = kmalloc(sizeof(*mst_pcmcia_device), GFP_KERNEL); 174 mst_pcmcia_device = kzalloc(sizeof(*mst_pcmcia_device), GFP_KERNEL);
175 if (!mst_pcmcia_device) 175 if (!mst_pcmcia_device)
176 return -ENOMEM; 176 return -ENOMEM;
177 memset(mst_pcmcia_device, 0, sizeof(*mst_pcmcia_device));
178 mst_pcmcia_device->name = "pxa2xx-pcmcia"; 177 mst_pcmcia_device->name = "pxa2xx-pcmcia";
179 mst_pcmcia_device->dev.platform_data = &mst_pcmcia_ops; 178 mst_pcmcia_device->dev.platform_data = &mst_pcmcia_ops;
180 179
diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c
index 56c58831e80e..b5fdeec20b15 100644
--- a/drivers/pcmcia/pxa2xx_sharpsl.c
+++ b/drivers/pcmcia/pxa2xx_sharpsl.c
@@ -264,11 +264,10 @@ static int __init sharpsl_pcmcia_init(void)
264 int ret; 264 int ret;
265 265
266 sharpsl_pcmcia_ops.nr=platform_scoop_config->num_devs; 266 sharpsl_pcmcia_ops.nr=platform_scoop_config->num_devs;
267 sharpsl_pcmcia_device = kmalloc(sizeof(*sharpsl_pcmcia_device), GFP_KERNEL); 267 sharpsl_pcmcia_device = kzalloc(sizeof(*sharpsl_pcmcia_device), GFP_KERNEL);
268 if (!sharpsl_pcmcia_device) 268 if (!sharpsl_pcmcia_device)
269 return -ENOMEM; 269 return -ENOMEM;
270 270
271 memset(sharpsl_pcmcia_device, 0, sizeof(*sharpsl_pcmcia_device));
272 sharpsl_pcmcia_device->name = "pxa2xx-pcmcia"; 271 sharpsl_pcmcia_device->name = "pxa2xx-pcmcia";
273 sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops; 272 sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops;
274 sharpsl_pcmcia_device->dev.parent=platform_scoop_config->devs[0].dev; 273 sharpsl_pcmcia_device->dev.parent=platform_scoop_config->devs[0].dev;
diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c
index 0668384ebc8b..514609369836 100644
--- a/drivers/pcmcia/rsrc_mgr.c
+++ b/drivers/pcmcia/rsrc_mgr.c
@@ -98,10 +98,12 @@ int pcmcia_adjust_resource_info(adjust_t *adj)
98} 98}
99EXPORT_SYMBOL(pcmcia_adjust_resource_info); 99EXPORT_SYMBOL(pcmcia_adjust_resource_info);
100 100
101void pcmcia_validate_mem(struct pcmcia_socket *s) 101int pcmcia_validate_mem(struct pcmcia_socket *s)
102{ 102{
103 if (s->resource_ops->validate_mem) 103 if (s->resource_ops->validate_mem)
104 s->resource_ops->validate_mem(s); 104 return s->resource_ops->validate_mem(s);
105 /* if there is no callback, we can assume that everything is OK */
106 return 0;
105} 107}
106EXPORT_SYMBOL(pcmcia_validate_mem); 108EXPORT_SYMBOL(pcmcia_validate_mem);
107 109
@@ -164,3 +166,105 @@ struct pccard_resource_ops pccard_static_ops = {
164 .exit = NULL, 166 .exit = NULL,
165}; 167};
166EXPORT_SYMBOL(pccard_static_ops); 168EXPORT_SYMBOL(pccard_static_ops);
169
170
171#ifdef CONFIG_PCCARD_IODYN
172
173static struct resource *
174make_resource(unsigned long b, unsigned long n, int flags, char *name)
175{
176 struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
177
178 if (res) {
179 res->name = name;
180 res->start = b;
181 res->end = b + n - 1;
182 res->flags = flags;
183 }
184 return res;
185}
186
187struct pcmcia_align_data {
188 unsigned long mask;
189 unsigned long offset;
190};
191
192static void pcmcia_align(void *align_data, struct resource *res,
193 unsigned long size, unsigned long align)
194{
195 struct pcmcia_align_data *data = align_data;
196 unsigned long start;
197
198 start = (res->start & ~data->mask) + data->offset;
199 if (start < res->start)
200 start += data->mask + 1;
201 res->start = start;
202
203#ifdef CONFIG_X86
204 if (res->flags & IORESOURCE_IO) {
205 if (start & 0x300) {
206 start = (start + 0x3ff) & ~0x3ff;
207 res->start = start;
208 }
209 }
210#endif
211
212#ifdef CONFIG_M68K
213 if (res->flags & IORESOURCE_IO) {
214 if ((res->start + size - 1) >= 1024)
215 res->start = res->end;
216 }
217#endif
218}
219
220
221static int iodyn_adjust_io_region(struct resource *res, unsigned long r_start,
222 unsigned long r_end, struct pcmcia_socket *s)
223{
224 return adjust_resource(res, r_start, r_end - r_start + 1);
225}
226
227
228static struct resource *iodyn_find_io_region(unsigned long base, int num,
229 unsigned long align, struct pcmcia_socket *s)
230{
231 struct resource *res = make_resource(0, num, IORESOURCE_IO,
232 s->dev.class_id);
233 struct pcmcia_align_data data;
234 unsigned long min = base;
235 int ret;
236
237 if (align == 0)
238 align = 0x10000;
239
240 data.mask = align - 1;
241 data.offset = base & data.mask;
242
243#ifdef CONFIG_PCI
244 if (s->cb_dev) {
245 ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1,
246 min, 0, pcmcia_align, &data);
247 } else
248#endif
249 ret = allocate_resource(&ioport_resource, res, num, min, ~0UL,
250 1, pcmcia_align, &data);
251
252 if (ret != 0) {
253 kfree(res);
254 res = NULL;
255 }
256 return res;
257}
258
259struct pccard_resource_ops pccard_iodyn_ops = {
260 .validate_mem = NULL,
261 .adjust_io_region = iodyn_adjust_io_region,
262 .find_io = iodyn_find_io_region,
263 .find_mem = NULL,
264 .adjust_resource = NULL,
265 .init = static_init,
266 .exit = NULL,
267};
268EXPORT_SYMBOL(pccard_iodyn_ops);
269
270#endif /* CONFIG_PCCARD_IODYN */
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c
index 00960a379b9c..5301ac60358f 100644
--- a/drivers/pcmcia/rsrc_nonstatic.c
+++ b/drivers/pcmcia/rsrc_nonstatic.c
@@ -75,10 +75,9 @@ static DECLARE_MUTEX(rsrc_sem);
75static struct resource * 75static struct resource *
76make_resource(unsigned long b, unsigned long n, int flags, char *name) 76make_resource(unsigned long b, unsigned long n, int flags, char *name)
77{ 77{
78 struct resource *res = kmalloc(sizeof(*res), GFP_KERNEL); 78 struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
79 79
80 if (res) { 80 if (res) {
81 memset(res, 0, sizeof(*res));
82 res->name = name; 81 res->name = name;
83 res->start = b; 82 res->start = b;
84 res->end = b + n - 1; 83 res->end = b + n - 1;
@@ -200,12 +199,11 @@ static void do_io_probe(struct pcmcia_socket *s, kio_addr_t base, kio_addr_t num
200 base, base+num-1); 199 base, base+num-1);
201 200
202 /* First, what does a floating port look like? */ 201 /* First, what does a floating port look like? */
203 b = kmalloc(256, GFP_KERNEL); 202 b = kzalloc(256, GFP_KERNEL);
204 if (!b) { 203 if (!b) {
205 printk(KERN_ERR "do_io_probe: unable to kmalloc 256 bytes"); 204 printk(KERN_ERR "do_io_probe: unable to kmalloc 256 bytes");
206 return; 205 return;
207 } 206 }
208 memset(b, 0, 256);
209 for (i = base, most = 0; i < base+num; i += 8) { 207 for (i = base, most = 0; i < base+num; i += 8) {
210 res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA IO probe"); 208 res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA IO probe");
211 if (!res) 209 if (!res)
@@ -407,69 +405,79 @@ static int do_mem_probe(u_long base, u_long num, struct pcmcia_socket *s)
407 405
408static u_long inv_probe(struct resource_map *m, struct pcmcia_socket *s) 406static u_long inv_probe(struct resource_map *m, struct pcmcia_socket *s)
409{ 407{
410 struct socket_data *s_data = s->resource_data; 408 struct socket_data *s_data = s->resource_data;
411 u_long ok; 409 u_long ok;
412 if (m == &s_data->mem_db) 410 if (m == &s_data->mem_db)
413 return 0; 411 return 0;
414 ok = inv_probe(m->next, s); 412 ok = inv_probe(m->next, s);
415 if (ok) { 413 if (ok) {
416 if (m->base >= 0x100000) 414 if (m->base >= 0x100000)
417 sub_interval(&s_data->mem_db, m->base, m->num); 415 sub_interval(&s_data->mem_db, m->base, m->num);
418 return ok; 416 return ok;
419 } 417 }
420 if (m->base < 0x100000) 418 if (m->base < 0x100000)
421 return 0; 419 return 0;
422 return do_mem_probe(m->base, m->num, s); 420 return do_mem_probe(m->base, m->num, s);
423} 421}
424 422
425static void validate_mem(struct pcmcia_socket *s, unsigned int probe_mask) 423static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
426{ 424{
427 struct resource_map *m, mm; 425 struct resource_map *m, mm;
428 static u_char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 }; 426 static unsigned char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
429 u_long b, i, ok = 0; 427 unsigned long b, i, ok = 0;
430 struct socket_data *s_data = s->resource_data; 428 struct socket_data *s_data = s->resource_data;
431 429
432 /* We do up to four passes through the list */ 430 /* We do up to four passes through the list */
433 if (probe_mask & MEM_PROBE_HIGH) { 431 if (probe_mask & MEM_PROBE_HIGH) {
434 if (inv_probe(s_data->mem_db.next, s) > 0) 432 if (inv_probe(s_data->mem_db.next, s) > 0)
435 return; 433 return 0;
436 printk(KERN_NOTICE "cs: warning: no high memory space " 434 printk(KERN_NOTICE "cs: warning: no high memory space "
437 "available!\n"); 435 "available!\n");
438 } 436 return -ENODEV;
439 if ((probe_mask & MEM_PROBE_LOW) == 0)
440 return;
441 for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
442 mm = *m;
443 /* Only probe < 1 MB */
444 if (mm.base >= 0x100000) continue;
445 if ((mm.base | mm.num) & 0xffff) {
446 ok += do_mem_probe(mm.base, mm.num, s);
447 continue;
448 } 437 }
449 /* Special probe for 64K-aligned block */ 438
450 for (i = 0; i < 4; i++) { 439 for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
451 b = order[i] << 12; 440 mm = *m;
452 if ((b >= mm.base) && (b+0x10000 <= mm.base+mm.num)) { 441 /* Only probe < 1 MB */
453 if (ok >= mem_limit) 442 if (mm.base >= 0x100000)
454 sub_interval(&s_data->mem_db, b, 0x10000); 443 continue;
455 else 444 if ((mm.base | mm.num) & 0xffff) {
456 ok += do_mem_probe(b, 0x10000, s); 445 ok += do_mem_probe(mm.base, mm.num, s);
457 } 446 continue;
447 }
448 /* Special probe for 64K-aligned block */
449 for (i = 0; i < 4; i++) {
450 b = order[i] << 12;
451 if ((b >= mm.base) && (b+0x10000 <= mm.base+mm.num)) {
452 if (ok >= mem_limit)
453 sub_interval(&s_data->mem_db, b, 0x10000);
454 else
455 ok += do_mem_probe(b, 0x10000, s);
456 }
457 }
458 } 458 }
459 } 459
460 if (ok > 0)
461 return 0;
462
463 return -ENODEV;
460} 464}
461 465
462#else /* CONFIG_PCMCIA_PROBE */ 466#else /* CONFIG_PCMCIA_PROBE */
463 467
464static void validate_mem(struct pcmcia_socket *s, unsigned int probe_mask) 468static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
465{ 469{
466 struct resource_map *m, mm; 470 struct resource_map *m, mm;
467 struct socket_data *s_data = s->resource_data; 471 struct socket_data *s_data = s->resource_data;
472 unsigned long ok = 0;
468 473
469 for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) { 474 for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
470 mm = *m; 475 mm = *m;
471 do_mem_probe(mm.base, mm.num, s); 476 ok += do_mem_probe(mm.base, mm.num, s);
472 } 477 }
478 if (ok > 0)
479 return 0;
480 return -ENODEV;
473} 481}
474 482
475#endif /* CONFIG_PCMCIA_PROBE */ 483#endif /* CONFIG_PCMCIA_PROBE */
@@ -478,27 +486,30 @@ static void validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
478/* 486/*
479 * Locking note: Must be called with skt_sem held! 487 * Locking note: Must be called with skt_sem held!
480 */ 488 */
481static void pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s) 489static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
482{ 490{
483 struct socket_data *s_data = s->resource_data; 491 struct socket_data *s_data = s->resource_data;
484 if (probe_mem) { 492 unsigned int probe_mask = MEM_PROBE_LOW;
485 unsigned int probe_mask; 493 int ret = 0;
486 494
487 down(&rsrc_sem); 495 if (!probe_mem)
496 return 0;
488 497
489 probe_mask = MEM_PROBE_LOW; 498 down(&rsrc_sem);
490 if (s->features & SS_CAP_PAGE_REGS)
491 probe_mask = MEM_PROBE_HIGH;
492 499
493 if (probe_mask & ~s_data->rsrc_mem_probe) { 500 if (s->features & SS_CAP_PAGE_REGS)
501 probe_mask = MEM_PROBE_HIGH;
502
503 if (probe_mask & ~s_data->rsrc_mem_probe) {
504 if (s->state & SOCKET_PRESENT)
505 ret = validate_mem(s, probe_mask);
506 if (!ret)
494 s_data->rsrc_mem_probe |= probe_mask; 507 s_data->rsrc_mem_probe |= probe_mask;
508 }
495 509
496 if (s->state & SOCKET_PRESENT) 510 up(&rsrc_sem);
497 validate_mem(s, probe_mask);
498 }
499 511
500 up(&rsrc_sem); 512 return ret;
501 }
502} 513}
503 514
504struct pcmcia_align_data { 515struct pcmcia_align_data {
@@ -837,10 +848,9 @@ static int nonstatic_init(struct pcmcia_socket *s)
837{ 848{
838 struct socket_data *data; 849 struct socket_data *data;
839 850
840 data = kmalloc(sizeof(struct socket_data), GFP_KERNEL); 851 data = kzalloc(sizeof(struct socket_data), GFP_KERNEL);
841 if (!data) 852 if (!data)
842 return -ENOMEM; 853 return -ENOMEM;
843 memset(data, 0, sizeof(struct socket_data));
844 854
845 data->mem_db.next = &data->mem_db; 855 data->mem_db.next = &data->mem_db;
846 data->io_db.next = &data->io_db; 856 data->io_db.next = &data->io_db;
diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index 9e7ccd8a4321..ea7d9ca160b2 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -297,25 +297,6 @@ soc_common_pcmcia_get_status(struct pcmcia_socket *sock, unsigned int *status)
297 297
298 298
299/* 299/*
300 * Implements the get_socket() operation for the in-kernel PCMCIA
301 * service (formerly SS_GetSocket in Card Services). Not a very
302 * exciting routine.
303 *
304 * Returns: 0
305 */
306static int
307soc_common_pcmcia_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
308{
309 struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock);
310
311 debug(skt, 2, "\n");
312
313 *state = skt->cs_state;
314
315 return 0;
316}
317
318/*
319 * Implements the set_socket() operation for the in-kernel PCMCIA 300 * Implements the set_socket() operation for the in-kernel PCMCIA
320 * service (formerly SS_SetSocket in Card Services). We more or 301 * service (formerly SS_SetSocket in Card Services). We more or
321 * less punt all of this work and let the kernel handle the details 302 * less punt all of this work and let the kernel handle the details
@@ -528,7 +509,6 @@ static struct pccard_operations soc_common_pcmcia_operations = {
528 .init = soc_common_pcmcia_sock_init, 509 .init = soc_common_pcmcia_sock_init,
529 .suspend = soc_common_pcmcia_suspend, 510 .suspend = soc_common_pcmcia_suspend,
530 .get_status = soc_common_pcmcia_get_status, 511 .get_status = soc_common_pcmcia_get_status,
531 .get_socket = soc_common_pcmcia_get_socket,
532 .set_socket = soc_common_pcmcia_set_socket, 512 .set_socket = soc_common_pcmcia_set_socket,
533 .set_io_map = soc_common_pcmcia_set_io_map, 513 .set_io_map = soc_common_pcmcia_set_io_map,
534 .set_mem_map = soc_common_pcmcia_set_mem_map, 514 .set_mem_map = soc_common_pcmcia_set_mem_map,
@@ -665,13 +645,12 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops
665 645
666 down(&soc_pcmcia_sockets_lock); 646 down(&soc_pcmcia_sockets_lock);
667 647
668 sinfo = kmalloc(SKT_DEV_INFO_SIZE(nr), GFP_KERNEL); 648 sinfo = kzalloc(SKT_DEV_INFO_SIZE(nr), GFP_KERNEL);
669 if (!sinfo) { 649 if (!sinfo) {
670 ret = -ENOMEM; 650 ret = -ENOMEM;
671 goto out; 651 goto out;
672 } 652 }
673 653
674 memset(sinfo, 0, SKT_DEV_INFO_SIZE(nr));
675 sinfo->nskt = nr; 654 sinfo->nskt = nr;
676 655
677 /* 656 /*
diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c
index 4a3150a7854c..7a7744662d54 100644
--- a/drivers/pcmcia/socket_sysfs.c
+++ b/drivers/pcmcia/socket_sysfs.c
@@ -42,35 +42,28 @@
42 42
43static ssize_t pccard_show_type(struct class_device *dev, char *buf) 43static ssize_t pccard_show_type(struct class_device *dev, char *buf)
44{ 44{
45 int val;
46 struct pcmcia_socket *s = to_socket(dev); 45 struct pcmcia_socket *s = to_socket(dev);
47 46
48 if (!(s->state & SOCKET_PRESENT)) 47 if (!(s->state & SOCKET_PRESENT))
49 return -ENODEV; 48 return -ENODEV;
50 s->ops->get_status(s, &val); 49 if (s->state & SOCKET_CARDBUS)
51 if (val & SS_CARDBUS)
52 return sprintf(buf, "32-bit\n"); 50 return sprintf(buf, "32-bit\n");
53 if (val & SS_DETECT) 51 return sprintf(buf, "16-bit\n");
54 return sprintf(buf, "16-bit\n");
55 return sprintf(buf, "invalid\n");
56} 52}
57static CLASS_DEVICE_ATTR(card_type, 0400, pccard_show_type, NULL); 53static CLASS_DEVICE_ATTR(card_type, 0444, pccard_show_type, NULL);
58 54
59static ssize_t pccard_show_voltage(struct class_device *dev, char *buf) 55static ssize_t pccard_show_voltage(struct class_device *dev, char *buf)
60{ 56{
61 int val;
62 struct pcmcia_socket *s = to_socket(dev); 57 struct pcmcia_socket *s = to_socket(dev);
63 58
64 if (!(s->state & SOCKET_PRESENT)) 59 if (!(s->state & SOCKET_PRESENT))
65 return -ENODEV; 60 return -ENODEV;
66 s->ops->get_status(s, &val); 61 if (s->socket.Vcc)
67 if (val & SS_3VCARD) 62 return sprintf(buf, "%d.%dV\n", s->socket.Vcc / 10,
68 return sprintf(buf, "3.3V\n"); 63 s->socket.Vcc % 10);
69 if (val & SS_XVCARD) 64 return sprintf(buf, "X.XV\n");
70 return sprintf(buf, "X.XV\n");
71 return sprintf(buf, "5.0V\n");
72} 65}
73static CLASS_DEVICE_ATTR(card_voltage, 0400, pccard_show_voltage, NULL); 66static CLASS_DEVICE_ATTR(card_voltage, 0444, pccard_show_voltage, NULL);
74 67
75static ssize_t pccard_show_vpp(struct class_device *dev, char *buf) 68static ssize_t pccard_show_vpp(struct class_device *dev, char *buf)
76{ 69{
@@ -79,7 +72,7 @@ static ssize_t pccard_show_vpp(struct class_device *dev, char *buf)
79 return -ENODEV; 72 return -ENODEV;
80 return sprintf(buf, "%d.%dV\n", s->socket.Vpp / 10, s->socket.Vpp % 10); 73 return sprintf(buf, "%d.%dV\n", s->socket.Vpp / 10, s->socket.Vpp % 10);
81} 74}
82static CLASS_DEVICE_ATTR(card_vpp, 0400, pccard_show_vpp, NULL); 75static CLASS_DEVICE_ATTR(card_vpp, 0444, pccard_show_vpp, NULL);
83 76
84static ssize_t pccard_show_vcc(struct class_device *dev, char *buf) 77static ssize_t pccard_show_vcc(struct class_device *dev, char *buf)
85{ 78{
@@ -88,7 +81,7 @@ static ssize_t pccard_show_vcc(struct class_device *dev, char *buf)
88 return -ENODEV; 81 return -ENODEV;
89 return sprintf(buf, "%d.%dV\n", s->socket.Vcc / 10, s->socket.Vcc % 10); 82 return sprintf(buf, "%d.%dV\n", s->socket.Vcc / 10, s->socket.Vcc % 10);
90} 83}
91static CLASS_DEVICE_ATTR(card_vcc, 0400, pccard_show_vcc, NULL); 84static CLASS_DEVICE_ATTR(card_vcc, 0444, pccard_show_vcc, NULL);
92 85
93 86
94static ssize_t pccard_store_insert(struct class_device *dev, const char *buf, size_t count) 87static ssize_t pccard_store_insert(struct class_device *dev, const char *buf, size_t count)
@@ -292,10 +285,9 @@ static ssize_t pccard_store_cis(struct kobject *kobj, char *buf, loff_t off, siz
292 if (!(s->state & SOCKET_PRESENT)) 285 if (!(s->state & SOCKET_PRESENT))
293 return -ENODEV; 286 return -ENODEV;
294 287
295 cis = kmalloc(sizeof(cisdump_t), GFP_KERNEL); 288 cis = kzalloc(sizeof(cisdump_t), GFP_KERNEL);
296 if (!cis) 289 if (!cis)
297 return -ENOMEM; 290 return -ENOMEM;
298 memset(cis, 0, sizeof(cisdump_t));
299 291
300 cis->Length = count + 1; 292 cis->Length = count + 1;
301 memcpy(cis->Data, buf, count); 293 memcpy(cis->Data, buf, count);
diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c
index e31263864377..73bad1d5cb23 100644
--- a/drivers/pcmcia/tcic.c
+++ b/drivers/pcmcia/tcic.c
@@ -181,13 +181,6 @@ static void tcic_setl(u_char reg, u_int data)
181 outw(data >> 16, tcic_base+reg+2); 181 outw(data >> 16, tcic_base+reg+2);
182} 182}
183 183
184static u_char tcic_aux_getb(u_short reg)
185{
186 u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
187 tcic_setb(TCIC_MODE, mode);
188 return tcic_getb(TCIC_AUX);
189}
190
191static void tcic_aux_setb(u_short reg, u_char data) 184static void tcic_aux_setb(u_short reg, u_char data)
192{ 185{
193 u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg; 186 u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
@@ -641,59 +634,6 @@ static int tcic_get_status(struct pcmcia_socket *sock, u_int *value)
641 debug(1, "GetStatus(%d) = %#2.2x\n", psock, *value); 634 debug(1, "GetStatus(%d) = %#2.2x\n", psock, *value);
642 return 0; 635 return 0;
643} /* tcic_get_status */ 636} /* tcic_get_status */
644
645/*====================================================================*/
646
647static int tcic_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
648{
649 u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
650 u_char reg;
651 u_short scf1, scf2;
652
653 tcic_setl(TCIC_ADDR, (psock << TCIC_ADDR_SS_SHFT)
654 | TCIC_ADDR_INDREG | TCIC_SCF1(psock));
655 scf1 = tcic_getw(TCIC_DATA);
656 state->flags = (scf1 & TCIC_SCF1_IOSTS) ? SS_IOCARD : 0;
657 state->flags |= (scf1 & TCIC_SCF1_DMA_MASK) ? SS_DMA_MODE : 0;
658 state->flags |= (scf1 & TCIC_SCF1_SPKR) ? SS_SPKR_ENA : 0;
659 if (tcic_getb(TCIC_SCTRL) & TCIC_SCTRL_ENA)
660 state->flags |= SS_OUTPUT_ENA;
661 state->io_irq = scf1 & TCIC_SCF1_IRQ_MASK;
662 if (state->io_irq == 1) state->io_irq = 11;
663
664 reg = tcic_getb(TCIC_PWR);
665 state->Vcc = state->Vpp = 0;
666 if (reg & TCIC_PWR_VCC(psock)) {
667 if (reg & TCIC_PWR_VPP(psock))
668 state->Vcc = 50;
669 else
670 state->Vcc = state->Vpp = 50;
671 } else {
672 if (reg & TCIC_PWR_VPP(psock)) {
673 state->Vcc = 50;
674 state->Vpp = 120;
675 }
676 }
677 reg = tcic_aux_getb(TCIC_AUX_ILOCK);
678 state->flags |= (reg & TCIC_ILOCK_CRESET) ? SS_RESET : 0;
679
680 /* Card status change interrupt mask */
681 tcic_setw(TCIC_ADDR, TCIC_SCF2(psock));
682 scf2 = tcic_getw(TCIC_DATA);
683 state->csc_mask = (scf2 & TCIC_SCF2_MCD) ? 0 : SS_DETECT;
684 if (state->flags & SS_IOCARD) {
685 state->csc_mask |= (scf2 & TCIC_SCF2_MLBAT1) ? 0 : SS_STSCHG;
686 } else {
687 state->csc_mask |= (scf2 & TCIC_SCF2_MLBAT1) ? 0 : SS_BATDEAD;
688 state->csc_mask |= (scf2 & TCIC_SCF2_MLBAT2) ? 0 : SS_BATWARN;
689 state->csc_mask |= (scf2 & TCIC_SCF2_MRDY) ? 0 : SS_READY;
690 }
691
692 debug(1, "GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, "
693 "io_irq %d, csc_mask %#2.2x\n", psock, state->flags,
694 state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
695 return 0;
696} /* tcic_get_socket */
697 637
698/*====================================================================*/ 638/*====================================================================*/
699 639
@@ -874,7 +814,6 @@ static int tcic_init(struct pcmcia_socket *s)
874static struct pccard_operations tcic_operations = { 814static struct pccard_operations tcic_operations = {
875 .init = tcic_init, 815 .init = tcic_init,
876 .get_status = tcic_get_status, 816 .get_status = tcic_get_status,
877 .get_socket = tcic_get_socket,
878 .set_socket = tcic_set_socket, 817 .set_socket = tcic_set_socket,
879 .set_io_map = tcic_set_io_map, 818 .set_io_map = tcic_set_io_map,
880 .set_mem_map = tcic_set_mem_map, 819 .set_mem_map = tcic_set_mem_map,
diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h
index 539b5cd1a598..d5b4ff74462e 100644
--- a/drivers/pcmcia/ti113x.h
+++ b/drivers/pcmcia/ti113x.h
@@ -873,7 +873,7 @@ static int ti1250_override(struct yenta_socket *socket)
873 * Some fixup code to make everybody happy (TM). 873 * Some fixup code to make everybody happy (TM).
874 */ 874 */
875 875
876#ifdef CONFIG_CARDBUS 876#ifdef CONFIG_YENTA_ENE_TUNE
877/** 877/**
878 * set/clear various test bits: 878 * set/clear various test bits:
879 * Defaults to clear the bit. 879 * Defaults to clear the bit.
@@ -937,7 +937,7 @@ static int ene_override(struct yenta_socket *socket)
937} 937}
938#else 938#else
939# define ene_override ti1250_override 939# define ene_override ti1250_override
940#endif 940#endif /* !CONFIG_YENTA_ENE_TUNE */
941 941
942#endif /* _LINUX_TI113X_H */ 942#endif /* _LINUX_TI113X_H */
943 943
diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c
index 38a028c725d4..24c547ef512b 100644
--- a/drivers/pcmcia/vrc4171_card.c
+++ b/drivers/pcmcia/vrc4171_card.c
@@ -301,75 +301,6 @@ static int pccard_get_status(struct pcmcia_socket *sock, u_int *value)
301 return 0; 301 return 0;
302} 302}
303 303
304static inline u_char get_Vcc_value(uint8_t voltage)
305{
306 switch (voltage) {
307 case VCC_STATUS_3V:
308 return 33;
309 case VCC_STATUS_5V:
310 return 50;
311 default:
312 break;
313 }
314
315 return 0;
316}
317
318static inline u_char get_Vpp_value(uint8_t power, u_char Vcc)
319{
320 if ((power & 0x03) == 0x01 || (power & 0x03) == 0x02)
321 return Vcc;
322
323 return 0;
324}
325
326static int pccard_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
327{
328 unsigned int slot;
329 uint8_t power, voltage, control, cscint;
330
331 if (sock == NULL || sock->sock >= CARD_MAX_SLOTS || state == NULL)
332 return -EINVAL;
333
334 slot = sock->sock;
335
336 power = exca_read_byte(slot, I365_POWER);
337 voltage = exca_read_byte(slot, CARD_VOLTAGE_SELECT);
338
339 state->Vcc = get_Vcc_value(voltage);
340 state->Vpp = get_Vpp_value(power, state->Vcc);
341
342 state->flags = 0;
343 if (power & POWER_ENABLE)
344 state->flags |= SS_PWR_AUTO;
345 if (power & I365_PWR_OUT)
346 state->flags |= SS_OUTPUT_ENA;
347
348 control = exca_read_byte(slot, I365_INTCTL);
349 if (control & I365_PC_IOCARD)
350 state->flags |= SS_IOCARD;
351 if (!(control & I365_PC_RESET))
352 state->flags |= SS_RESET;
353
354 cscint = exca_read_byte(slot, I365_CSCINT);
355 state->csc_mask = 0;
356 if (state->flags & SS_IOCARD) {
357 if (cscint & I365_CSC_STSCHG)
358 state->flags |= SS_STSCHG;
359 } else {
360 if (cscint & I365_CSC_BVD1)
361 state->csc_mask |= SS_BATDEAD;
362 if (cscint & I365_CSC_BVD2)
363 state->csc_mask |= SS_BATWARN;
364 }
365 if (cscint & I365_CSC_READY)
366 state->csc_mask |= SS_READY;
367 if (cscint & I365_CSC_DETECT)
368 state->csc_mask |= SS_DETECT;
369
370 return 0;
371}
372
373static inline uint8_t set_Vcc_value(u_char Vcc) 304static inline uint8_t set_Vcc_value(u_char Vcc)
374{ 305{
375 switch (Vcc) { 306 switch (Vcc) {
@@ -551,7 +482,6 @@ static int pccard_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map
551static struct pccard_operations vrc4171_pccard_operations = { 482static struct pccard_operations vrc4171_pccard_operations = {
552 .init = pccard_init, 483 .init = pccard_init,
553 .get_status = pccard_get_status, 484 .get_status = pccard_get_status,
554 .get_socket = pccard_get_socket,
555 .set_socket = pccard_set_socket, 485 .set_socket = pccard_set_socket,
556 .set_io_map = pccard_set_io_map, 486 .set_io_map = pccard_set_io_map,
557 .set_mem_map = pccard_set_mem_map, 487 .set_mem_map = pccard_set_mem_map,
diff --git a/drivers/pcmcia/vrc4173_cardu.c b/drivers/pcmcia/vrc4173_cardu.c
index db91259dc50e..1b277d2c1c96 100644
--- a/drivers/pcmcia/vrc4173_cardu.c
+++ b/drivers/pcmcia/vrc4173_cardu.c
@@ -198,48 +198,6 @@ static int cardu_get_status(unsigned int sock, u_int *value)
198 return 0; 198 return 0;
199} 199}
200 200
201static inline u_char get_Vcc_value(uint8_t val)
202{
203 switch (val & VCC_MASK) {
204 case VCC_3V:
205 return 33;
206 case VCC_5V:
207 return 50;
208 }
209
210 return 0;
211}
212
213static inline u_char get_Vpp_value(uint8_t val)
214{
215 switch (val & VPP_MASK) {
216 case VPP_12V:
217 return 120;
218 case VPP_VCC:
219 return get_Vcc_value(val);
220 }
221
222 return 0;
223}
224
225static int cardu_get_socket(unsigned int sock, socket_state_t *state)
226{
227 vrc4173_socket_t *socket = &cardu_sockets[sock];
228 uint8_t val;
229
230 val = exca_readb(socket, PWR_CNT);
231 state->Vcc = get_Vcc_value(val);
232 state->Vpp = get_Vpp_value(val);
233 state->flags = 0;
234 if (val & CARD_OUT_EN) state->flags |= SS_OUTPUT_ENA;
235
236 val = exca_readb(socket, INT_GEN_CNT);
237 if (!(val & CARD_REST0)) state->flags |= SS_RESET;
238 if (val & CARD_TYPE_IO) state->flags |= SS_IOCARD;
239
240 return 0;
241}
242
243static inline uint8_t set_Vcc_value(u_char Vcc) 201static inline uint8_t set_Vcc_value(u_char Vcc)
244{ 202{
245 switch (Vcc) { 203 switch (Vcc) {
@@ -431,7 +389,6 @@ static struct pccard_operations cardu_operations = {
431 .register_callback = cardu_register_callback, 389 .register_callback = cardu_register_callback,
432 .inquire_socket = cardu_inquire_socket, 390 .inquire_socket = cardu_inquire_socket,
433 .get_status = cardu_get_status, 391 .get_status = cardu_get_status,
434 .get_socket = cardu_get_socket,
435 .set_socket = cardu_set_socket, 392 .set_socket = cardu_set_socket,
436 .get_io_map = cardu_get_io_map, 393 .get_io_map = cardu_get_io_map,
437 .set_io_map = cardu_set_io_map, 394 .set_io_map = cardu_set_io_map,
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
index ec6ab65f0872..4145eb83b9b6 100644
--- a/drivers/pcmcia/yenta_socket.c
+++ b/drivers/pcmcia/yenta_socket.c
@@ -49,7 +49,13 @@ MODULE_PARM_DESC(pwr_irqs_off, "Force IRQs off during power-on of slot. Use only
49#define to_cycles(ns) ((ns)/120) 49#define to_cycles(ns) ((ns)/120)
50#define to_ns(cycles) ((cycles)*120) 50#define to_ns(cycles) ((cycles)*120)
51 51
52/**
53 * yenta PCI irq probing.
54 * currently only used in the TI/EnE initialization code
55 */
56#ifdef CONFIG_YENTA_TI
52static int yenta_probe_cb_irq(struct yenta_socket *socket); 57static int yenta_probe_cb_irq(struct yenta_socket *socket);
58#endif
53 59
54 60
55static unsigned int override_bios; 61static unsigned int override_bios;
@@ -224,95 +230,6 @@ static int yenta_get_status(struct pcmcia_socket *sock, unsigned int *value)
224 return 0; 230 return 0;
225} 231}
226 232
227static void yenta_get_power(struct yenta_socket *socket, socket_state_t *state)
228{
229 if (!(cb_readl(socket, CB_SOCKET_STATE) & CB_CBCARD) &&
230 (socket->flags & YENTA_16BIT_POWER_EXCA)) {
231 u8 reg, vcc, vpp;
232
233 reg = exca_readb(socket, I365_POWER);
234 vcc = reg & I365_VCC_MASK;
235 vpp = reg & I365_VPP1_MASK;
236 state->Vcc = state->Vpp = 0;
237
238 if (socket->flags & YENTA_16BIT_POWER_DF) {
239 if (vcc == I365_VCC_3V)
240 state->Vcc = 33;
241 if (vcc == I365_VCC_5V)
242 state->Vcc = 50;
243 if (vpp == I365_VPP1_5V)
244 state->Vpp = state->Vcc;
245 if (vpp == I365_VPP1_12V)
246 state->Vpp = 120;
247 } else {
248 if (reg & I365_VCC_5V) {
249 state->Vcc = 50;
250 if (vpp == I365_VPP1_5V)
251 state->Vpp = 50;
252 if (vpp == I365_VPP1_12V)
253 state->Vpp = 120;
254 }
255 }
256 } else {
257 u32 control;
258
259 control = cb_readl(socket, CB_SOCKET_CONTROL);
260
261 switch (control & CB_SC_VCC_MASK) {
262 case CB_SC_VCC_5V: state->Vcc = 50; break;
263 case CB_SC_VCC_3V: state->Vcc = 33; break;
264 default: state->Vcc = 0;
265 }
266
267 switch (control & CB_SC_VPP_MASK) {
268 case CB_SC_VPP_12V: state->Vpp = 120; break;
269 case CB_SC_VPP_5V: state->Vpp = 50; break;
270 case CB_SC_VPP_3V: state->Vpp = 33; break;
271 default: state->Vpp = 0;
272 }
273 }
274}
275
276static int yenta_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
277{
278 struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
279 u8 reg;
280 u32 control;
281
282 control = cb_readl(socket, CB_SOCKET_CONTROL);
283
284 yenta_get_power(socket, state);
285 state->io_irq = socket->io_irq;
286
287 if (cb_readl(socket, CB_SOCKET_STATE) & CB_CBCARD) {
288 u16 bridge = config_readw(socket, CB_BRIDGE_CONTROL);
289 if (bridge & CB_BRIDGE_CRST)
290 state->flags |= SS_RESET;
291 return 0;
292 }
293
294 /* 16-bit card state.. */
295 reg = exca_readb(socket, I365_POWER);
296 state->flags = (reg & I365_PWR_AUTO) ? SS_PWR_AUTO : 0;
297 state->flags |= (reg & I365_PWR_OUT) ? SS_OUTPUT_ENA : 0;
298
299 reg = exca_readb(socket, I365_INTCTL);
300 state->flags |= (reg & I365_PC_RESET) ? 0 : SS_RESET;
301 state->flags |= (reg & I365_PC_IOCARD) ? SS_IOCARD : 0;
302
303 reg = exca_readb(socket, I365_CSCINT);
304 state->csc_mask = (reg & I365_CSC_DETECT) ? SS_DETECT : 0;
305 if (state->flags & SS_IOCARD) {
306 state->csc_mask |= (reg & I365_CSC_STSCHG) ? SS_STSCHG : 0;
307 } else {
308 state->csc_mask |= (reg & I365_CSC_BVD1) ? SS_BATDEAD : 0;
309 state->csc_mask |= (reg & I365_CSC_BVD2) ? SS_BATWARN : 0;
310 state->csc_mask |= (reg & I365_CSC_READY) ? SS_READY : 0;
311 }
312
313 return 0;
314}
315
316static void yenta_set_power(struct yenta_socket *socket, socket_state_t *state) 233static void yenta_set_power(struct yenta_socket *socket, socket_state_t *state)
317{ 234{
318 /* some birdges require to use the ExCA registers to power 16bit cards */ 235 /* some birdges require to use the ExCA registers to power 16bit cards */
@@ -531,6 +448,9 @@ static irqreturn_t yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs)
531 448
532 csc = exca_readb(socket, I365_CSC); 449 csc = exca_readb(socket, I365_CSC);
533 450
451 if (!(cb_event || csc))
452 return IRQ_NONE;
453
534 events = (cb_event & (CB_CD1EVENT | CB_CD2EVENT)) ? SS_DETECT : 0 ; 454 events = (cb_event & (CB_CD1EVENT | CB_CD2EVENT)) ? SS_DETECT : 0 ;
535 events |= (csc & I365_CSC_DETECT) ? SS_DETECT : 0; 455 events |= (csc & I365_CSC_DETECT) ? SS_DETECT : 0;
536 if (exca_readb(socket, I365_INTCTL) & I365_PC_IOCARD) { 456 if (exca_readb(socket, I365_INTCTL) & I365_PC_IOCARD) {
@@ -544,10 +464,7 @@ static irqreturn_t yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs)
544 if (events) 464 if (events)
545 pcmcia_parse_events(&socket->socket, events); 465 pcmcia_parse_events(&socket->socket, events);
546 466
547 if (cb_event || csc) 467 return IRQ_HANDLED;
548 return IRQ_HANDLED;
549
550 return IRQ_NONE;
551} 468}
552 469
553static void yenta_interrupt_wrapper(unsigned long data) 470static void yenta_interrupt_wrapper(unsigned long data)
@@ -828,17 +745,24 @@ static struct pccard_operations yenta_socket_operations = {
828 .init = yenta_sock_init, 745 .init = yenta_sock_init,
829 .suspend = yenta_sock_suspend, 746 .suspend = yenta_sock_suspend,
830 .get_status = yenta_get_status, 747 .get_status = yenta_get_status,
831 .get_socket = yenta_get_socket,
832 .set_socket = yenta_set_socket, 748 .set_socket = yenta_set_socket,
833 .set_io_map = yenta_set_io_map, 749 .set_io_map = yenta_set_io_map,
834 .set_mem_map = yenta_set_mem_map, 750 .set_mem_map = yenta_set_mem_map,
835}; 751};
836 752
837 753
754#ifdef CONFIG_YENTA_TI
838#include "ti113x.h" 755#include "ti113x.h"
756#endif
757#ifdef CONFIG_YENTA_RICOH
839#include "ricoh.h" 758#include "ricoh.h"
759#endif
760#ifdef CONFIG_YENTA_TOSHIBA
840#include "topic.h" 761#include "topic.h"
762#endif
763#ifdef CONFIG_YENTA_O2
841#include "o2micro.h" 764#include "o2micro.h"
765#endif
842 766
843enum { 767enum {
844 CARDBUS_TYPE_DEFAULT = -1, 768 CARDBUS_TYPE_DEFAULT = -1,
@@ -858,6 +782,7 @@ enum {
858 * initialization sequences etc details. List them here.. 782 * initialization sequences etc details. List them here..
859 */ 783 */
860static struct cardbus_type cardbus_type[] = { 784static struct cardbus_type cardbus_type[] = {
785#ifdef CONFIG_YENTA_TI
861 [CARDBUS_TYPE_TI] = { 786 [CARDBUS_TYPE_TI] = {
862 .override = ti_override, 787 .override = ti_override,
863 .save_state = ti_save_state, 788 .save_state = ti_save_state,
@@ -882,27 +807,36 @@ static struct cardbus_type cardbus_type[] = {
882 .restore_state = ti_restore_state, 807 .restore_state = ti_restore_state,
883 .sock_init = ti_init, 808 .sock_init = ti_init,
884 }, 809 },
810#endif
811#ifdef CONFIG_YENTA_RICOH
885 [CARDBUS_TYPE_RICOH] = { 812 [CARDBUS_TYPE_RICOH] = {
886 .override = ricoh_override, 813 .override = ricoh_override,
887 .save_state = ricoh_save_state, 814 .save_state = ricoh_save_state,
888 .restore_state = ricoh_restore_state, 815 .restore_state = ricoh_restore_state,
889 }, 816 },
817#endif
818#ifdef CONFIG_YENTA_TOSHIBA
890 [CARDBUS_TYPE_TOPIC95] = { 819 [CARDBUS_TYPE_TOPIC95] = {
891 .override = topic95_override, 820 .override = topic95_override,
892 }, 821 },
893 [CARDBUS_TYPE_TOPIC97] = { 822 [CARDBUS_TYPE_TOPIC97] = {
894 .override = topic97_override, 823 .override = topic97_override,
895 }, 824 },
825#endif
826#ifdef CONFIG_YENTA_O2
896 [CARDBUS_TYPE_O2MICRO] = { 827 [CARDBUS_TYPE_O2MICRO] = {
897 .override = o2micro_override, 828 .override = o2micro_override,
898 .restore_state = o2micro_restore_state, 829 .restore_state = o2micro_restore_state,
899 }, 830 },
831#endif
832#ifdef CONFIG_YENTA_TI
900 [CARDBUS_TYPE_ENE] = { 833 [CARDBUS_TYPE_ENE] = {
901 .override = ene_override, 834 .override = ene_override,
902 .save_state = ti_save_state, 835 .save_state = ti_save_state,
903 .restore_state = ti_restore_state, 836 .restore_state = ti_restore_state,
904 .sock_init = ti_init, 837 .sock_init = ti_init,
905 }, 838 },
839#endif
906}; 840};
907 841
908 842
@@ -948,6 +882,12 @@ static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mas
948} 882}
949 883
950 884
885/**
886 * yenta PCI irq probing.
887 * currently only used in the TI/EnE initialization code
888 */
889#ifdef CONFIG_YENTA_TI
890
951/* interrupt handler, only used during probing */ 891/* interrupt handler, only used during probing */
952static irqreturn_t yenta_probe_handler(int irq, void *dev_id, struct pt_regs *regs) 892static irqreturn_t yenta_probe_handler(int irq, void *dev_id, struct pt_regs *regs)
953{ 893{
@@ -1000,6 +940,7 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket)
1000 return (int) socket->probe_status; 940 return (int) socket->probe_status;
1001} 941}
1002 942
943#endif /* CONFIG_YENTA_TI */
1003 944
1004 945
1005/* 946/*
@@ -1078,10 +1019,9 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
1078 return -ENODEV; 1019 return -ENODEV;
1079 } 1020 }
1080 1021
1081 socket = kmalloc(sizeof(struct yenta_socket), GFP_KERNEL); 1022 socket = kzalloc(sizeof(struct yenta_socket), GFP_KERNEL);
1082 if (!socket) 1023 if (!socket)
1083 return -ENOMEM; 1024 return -ENOMEM;
1084 memset(socket, 0, sizeof(*socket));
1085 1025
1086 /* prepare pcmcia_socket */ 1026 /* prepare pcmcia_socket */
1087 socket->socket.ops = &yenta_socket_operations; 1027 socket->socket.ops = &yenta_socket_operations;
@@ -1263,6 +1203,7 @@ static struct pci_device_id yenta_table [] = {
1263 * advanced overrides instead. (I can't get the 1203 * advanced overrides instead. (I can't get the
1264 * data sheets for these devices. --rmk) 1204 * data sheets for these devices. --rmk)
1265 */ 1205 */
1206#ifdef CONFIG_YENTA_TI
1266 CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1210, TI), 1207 CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1210, TI),
1267 1208
1268 CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1130, TI113X), 1209 CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1130, TI113X),
@@ -1305,18 +1246,25 @@ static struct pci_device_id yenta_table [] = {
1305 CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1225, ENE), 1246 CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1225, ENE),
1306 CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1410, ENE), 1247 CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1410, ENE),
1307 CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1420, ENE), 1248 CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1420, ENE),
1249#endif /* CONFIG_YENTA_TI */
1308 1250
1251#ifdef CONFIG_YENTA_RICOH
1309 CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C465, RICOH), 1252 CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C465, RICOH),
1310 CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C466, RICOH), 1253 CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C466, RICOH),
1311 CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C475, RICOH), 1254 CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C475, RICOH),
1312 CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, RICOH), 1255 CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, RICOH),
1313 CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C478, RICOH), 1256 CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C478, RICOH),
1257#endif
1314 1258
1259#ifdef CONFIG_YENTA_TOSHIBA
1315 CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC95, TOPIC95), 1260 CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC95, TOPIC95),
1316 CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC97, TOPIC97), 1261 CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC97, TOPIC97),
1317 CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC100, TOPIC97), 1262 CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC100, TOPIC97),
1263#endif
1318 1264
1265#ifdef CONFIG_YENTA_O2
1319 CB_ID(PCI_VENDOR_ID_O2, PCI_ANY_ID, O2MICRO), 1266 CB_ID(PCI_VENDOR_ID_O2, PCI_ANY_ID, O2MICRO),
1267#endif
1320 1268
1321 /* match any cardbus bridge */ 1269 /* match any cardbus bridge */
1322 CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT), 1270 CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT),
diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c
index 7c5306499832..0c9edb7051f4 100644
--- a/drivers/scsi/pcmcia/aha152x_stub.c
+++ b/drivers/scsi/pcmcia/aha152x_stub.c
@@ -95,27 +95,21 @@ typedef struct scsi_info_t {
95} scsi_info_t; 95} scsi_info_t;
96 96
97static void aha152x_release_cs(dev_link_t *link); 97static void aha152x_release_cs(dev_link_t *link);
98static int aha152x_event(event_t event, int priority, 98static void aha152x_detach(struct pcmcia_device *p_dev);
99 event_callback_args_t *args); 99static void aha152x_config_cs(dev_link_t *link);
100
101static dev_link_t *aha152x_attach(void);
102static void aha152x_detach(dev_link_t *);
103 100
104static dev_link_t *dev_list; 101static dev_link_t *dev_list;
105static dev_info_t dev_info = "aha152x_cs";
106 102
107static dev_link_t *aha152x_attach(void) 103static int aha152x_attach(struct pcmcia_device *p_dev)
108{ 104{
109 scsi_info_t *info; 105 scsi_info_t *info;
110 client_reg_t client_reg;
111 dev_link_t *link; 106 dev_link_t *link;
112 int ret;
113 107
114 DEBUG(0, "aha152x_attach()\n"); 108 DEBUG(0, "aha152x_attach()\n");
115 109
116 /* Create new SCSI device */ 110 /* Create new SCSI device */
117 info = kmalloc(sizeof(*info), GFP_KERNEL); 111 info = kmalloc(sizeof(*info), GFP_KERNEL);
118 if (!info) return NULL; 112 if (!info) return -ENOMEM;
119 memset(info, 0, sizeof(*info)); 113 memset(info, 0, sizeof(*info));
120 link = &info->link; link->priv = info; 114 link = &info->link; link->priv = info;
121 115
@@ -129,26 +123,20 @@ static dev_link_t *aha152x_attach(void)
129 link->conf.IntType = INT_MEMORY_AND_IO; 123 link->conf.IntType = INT_MEMORY_AND_IO;
130 link->conf.Present = PRESENT_OPTION; 124 link->conf.Present = PRESENT_OPTION;
131 125
132 /* Register with Card Services */ 126 link->handle = p_dev;
133 link->next = dev_list; 127 p_dev->instance = link;
134 dev_list = link; 128
135 client_reg.dev_info = &dev_info; 129 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
136 client_reg.Version = 0x0210; 130 aha152x_config_cs(link);
137 client_reg.event_callback_args.client_data = link; 131
138 ret = pcmcia_register_client(&link->handle, &client_reg); 132 return 0;
139 if (ret != 0) {
140 cs_error(link->handle, RegisterClient, ret);
141 aha152x_detach(link);
142 return NULL;
143 }
144
145 return link;
146} /* aha152x_attach */ 133} /* aha152x_attach */
147 134
148/*====================================================================*/ 135/*====================================================================*/
149 136
150static void aha152x_detach(dev_link_t *link) 137static void aha152x_detach(struct pcmcia_device *p_dev)
151{ 138{
139 dev_link_t *link = dev_to_instance(p_dev);
152 dev_link_t **linkp; 140 dev_link_t **linkp;
153 141
154 DEBUG(0, "aha152x_detach(0x%p)\n", link); 142 DEBUG(0, "aha152x_detach(0x%p)\n", link);
@@ -162,9 +150,6 @@ static void aha152x_detach(dev_link_t *link)
162 if (link->state & DEV_CONFIG) 150 if (link->state & DEV_CONFIG)
163 aha152x_release_cs(link); 151 aha152x_release_cs(link);
164 152
165 if (link->handle)
166 pcmcia_deregister_client(link->handle);
167
168 /* Unlink device structure, free bits */ 153 /* Unlink device structure, free bits */
169 *linkp = link->next; 154 *linkp = link->next;
170 kfree(link->priv); 155 kfree(link->priv);
@@ -272,44 +257,31 @@ static void aha152x_release_cs(dev_link_t *link)
272 link->state &= ~DEV_CONFIG; 257 link->state &= ~DEV_CONFIG;
273} 258}
274 259
275static int aha152x_event(event_t event, int priority, 260static int aha152x_suspend(struct pcmcia_device *dev)
276 event_callback_args_t *args)
277{ 261{
278 dev_link_t *link = args->client_data; 262 dev_link_t *link = dev_to_instance(dev);
279 scsi_info_t *info = link->priv; 263
280
281 DEBUG(0, "aha152x_event(0x%06x)\n", event);
282
283 switch (event) {
284 case CS_EVENT_CARD_REMOVAL:
285 link->state &= ~DEV_PRESENT;
286 if (link->state & DEV_CONFIG)
287 aha152x_release_cs(link);
288 break;
289 case CS_EVENT_CARD_INSERTION:
290 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
291 aha152x_config_cs(link);
292 break;
293 case CS_EVENT_PM_SUSPEND:
294 link->state |= DEV_SUSPEND; 264 link->state |= DEV_SUSPEND;
295 /* Fall through... */
296 case CS_EVENT_RESET_PHYSICAL:
297 if (link->state & DEV_CONFIG) 265 if (link->state & DEV_CONFIG)
298 pcmcia_release_configuration(link->handle); 266 pcmcia_release_configuration(link->handle);
299 break; 267
300 case CS_EVENT_PM_RESUME: 268 return 0;
269}
270
271static int aha152x_resume(struct pcmcia_device *dev)
272{
273 dev_link_t *link = dev_to_instance(dev);
274 scsi_info_t *info = link->priv;
275
301 link->state &= ~DEV_SUSPEND; 276 link->state &= ~DEV_SUSPEND;
302 /* Fall through... */
303 case CS_EVENT_CARD_RESET:
304 if (link->state & DEV_CONFIG) { 277 if (link->state & DEV_CONFIG) {
305 Scsi_Cmnd tmp; 278 Scsi_Cmnd tmp;
306 pcmcia_request_configuration(link->handle, &link->conf); 279 pcmcia_request_configuration(link->handle, &link->conf);
307 tmp.device->host = info->host; 280 tmp.device->host = info->host;
308 aha152x_host_reset(&tmp); 281 aha152x_host_reset(&tmp);
309 } 282 }
310 break; 283
311 } 284 return 0;
312 return 0;
313} 285}
314 286
315static struct pcmcia_device_id aha152x_ids[] = { 287static struct pcmcia_device_id aha152x_ids[] = {
@@ -327,10 +299,11 @@ static struct pcmcia_driver aha152x_cs_driver = {
327 .drv = { 299 .drv = {
328 .name = "aha152x_cs", 300 .name = "aha152x_cs",
329 }, 301 },
330 .attach = aha152x_attach, 302 .probe = aha152x_attach,
331 .event = aha152x_event, 303 .remove = aha152x_detach,
332 .detach = aha152x_detach,
333 .id_table = aha152x_ids, 304 .id_table = aha152x_ids,
305 .suspend = aha152x_suspend,
306 .resume = aha152x_resume,
334}; 307};
335 308
336static int __init init_aha152x_cs(void) 309static int __init init_aha152x_cs(void)
diff --git a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c
index db8f5cd85ffe..788c58d805f3 100644
--- a/drivers/scsi/pcmcia/fdomain_stub.c
+++ b/drivers/scsi/pcmcia/fdomain_stub.c
@@ -80,29 +80,19 @@ typedef struct scsi_info_t {
80 80
81 81
82static void fdomain_release(dev_link_t *link); 82static void fdomain_release(dev_link_t *link);
83static int fdomain_event(event_t event, int priority, 83static void fdomain_detach(struct pcmcia_device *p_dev);
84 event_callback_args_t *args); 84static void fdomain_config(dev_link_t *link);
85 85
86static dev_link_t *fdomain_attach(void); 86static int fdomain_attach(struct pcmcia_device *p_dev)
87static void fdomain_detach(dev_link_t *);
88
89
90static dev_link_t *dev_list = NULL;
91
92static dev_info_t dev_info = "fdomain_cs";
93
94static dev_link_t *fdomain_attach(void)
95{ 87{
96 scsi_info_t *info; 88 scsi_info_t *info;
97 client_reg_t client_reg;
98 dev_link_t *link; 89 dev_link_t *link;
99 int ret; 90
100
101 DEBUG(0, "fdomain_attach()\n"); 91 DEBUG(0, "fdomain_attach()\n");
102 92
103 /* Create new SCSI device */ 93 /* Create new SCSI device */
104 info = kmalloc(sizeof(*info), GFP_KERNEL); 94 info = kmalloc(sizeof(*info), GFP_KERNEL);
105 if (!info) return NULL; 95 if (!info) return -ENOMEM;
106 memset(info, 0, sizeof(*info)); 96 memset(info, 0, sizeof(*info));
107 link = &info->link; link->priv = info; 97 link = &info->link; link->priv = info;
108 link->io.NumPorts1 = 0x10; 98 link->io.NumPorts1 = 0x10;
@@ -115,46 +105,27 @@ static dev_link_t *fdomain_attach(void)
115 link->conf.IntType = INT_MEMORY_AND_IO; 105 link->conf.IntType = INT_MEMORY_AND_IO;
116 link->conf.Present = PRESENT_OPTION; 106 link->conf.Present = PRESENT_OPTION;
117 107
118 /* Register with Card Services */ 108 link->handle = p_dev;
119 link->next = dev_list; 109 p_dev->instance = link;
120 dev_list = link; 110
121 client_reg.dev_info = &dev_info; 111 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
122 client_reg.Version = 0x0210; 112 fdomain_config(link);
123 client_reg.event_callback_args.client_data = link; 113
124 ret = pcmcia_register_client(&link->handle, &client_reg); 114 return 0;
125 if (ret != 0) {
126 cs_error(link->handle, RegisterClient, ret);
127 fdomain_detach(link);
128 return NULL;
129 }
130
131 return link;
132} /* fdomain_attach */ 115} /* fdomain_attach */
133 116
134/*====================================================================*/ 117/*====================================================================*/
135 118
136static void fdomain_detach(dev_link_t *link) 119static void fdomain_detach(struct pcmcia_device *p_dev)
137{ 120{
138 dev_link_t **linkp; 121 dev_link_t *link = dev_to_instance(p_dev);
139 122
140 DEBUG(0, "fdomain_detach(0x%p)\n", link); 123 DEBUG(0, "fdomain_detach(0x%p)\n", link);
141
142 /* Locate device structure */
143 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
144 if (*linkp == link) break;
145 if (*linkp == NULL)
146 return;
147 124
148 if (link->state & DEV_CONFIG) 125 if (link->state & DEV_CONFIG)
149 fdomain_release(link); 126 fdomain_release(link);
150 127
151 if (link->handle) 128 kfree(link->priv);
152 pcmcia_deregister_client(link->handle);
153
154 /* Unlink device structure, free bits */
155 *linkp = link->next;
156 kfree(link->priv);
157
158} /* fdomain_detach */ 129} /* fdomain_detach */
159 130
160/*====================================================================*/ 131/*====================================================================*/
@@ -256,43 +227,29 @@ static void fdomain_release(dev_link_t *link)
256 227
257/*====================================================================*/ 228/*====================================================================*/
258 229
259static int fdomain_event(event_t event, int priority, 230static int fdomain_suspend(struct pcmcia_device *dev)
260 event_callback_args_t *args)
261{ 231{
262 dev_link_t *link = args->client_data; 232 dev_link_t *link = dev_to_instance(dev);
263 233
264 DEBUG(1, "fdomain_event(0x%06x)\n", event);
265
266 switch (event) {
267 case CS_EVENT_CARD_REMOVAL:
268 link->state &= ~DEV_PRESENT;
269 if (link->state & DEV_CONFIG)
270 fdomain_release(link);
271 break;
272 case CS_EVENT_CARD_INSERTION:
273 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
274 fdomain_config(link);
275 break;
276 case CS_EVENT_PM_SUSPEND:
277 link->state |= DEV_SUSPEND; 234 link->state |= DEV_SUSPEND;
278 /* Fall through... */
279 case CS_EVENT_RESET_PHYSICAL:
280 if (link->state & DEV_CONFIG) 235 if (link->state & DEV_CONFIG)
281 pcmcia_release_configuration(link->handle); 236 pcmcia_release_configuration(link->handle);
282 break; 237
283 case CS_EVENT_PM_RESUME: 238 return 0;
239}
240
241static int fdomain_resume(struct pcmcia_device *dev)
242{
243 dev_link_t *link = dev_to_instance(dev);
244
284 link->state &= ~DEV_SUSPEND; 245 link->state &= ~DEV_SUSPEND;
285 /* Fall through... */
286 case CS_EVENT_CARD_RESET:
287 if (link->state & DEV_CONFIG) { 246 if (link->state & DEV_CONFIG) {
288 pcmcia_request_configuration(link->handle, &link->conf); 247 pcmcia_request_configuration(link->handle, &link->conf);
289 fdomain_16x0_bus_reset(NULL); 248 fdomain_16x0_bus_reset(NULL);
290 } 249 }
291 break;
292 }
293 return 0;
294} /* fdomain_event */
295 250
251 return 0;
252}
296 253
297static struct pcmcia_device_id fdomain_ids[] = { 254static struct pcmcia_device_id fdomain_ids[] = {
298 PCMCIA_DEVICE_PROD_ID12("IBM Corp.", "SCSI PCMCIA Card", 0xe3736c88, 0x859cad20), 255 PCMCIA_DEVICE_PROD_ID12("IBM Corp.", "SCSI PCMCIA Card", 0xe3736c88, 0x859cad20),
@@ -307,10 +264,11 @@ static struct pcmcia_driver fdomain_cs_driver = {
307 .drv = { 264 .drv = {
308 .name = "fdomain_cs", 265 .name = "fdomain_cs",
309 }, 266 },
310 .attach = fdomain_attach, 267 .probe = fdomain_attach,
311 .event = fdomain_event, 268 .remove = fdomain_detach,
312 .detach = fdomain_detach,
313 .id_table = fdomain_ids, 269 .id_table = fdomain_ids,
270 .suspend = fdomain_suspend,
271 .resume = fdomain_resume,
314}; 272};
315 273
316static int __init init_fdomain_cs(void) 274static int __init init_fdomain_cs(void)
@@ -321,7 +279,6 @@ static int __init init_fdomain_cs(void)
321static void __exit exit_fdomain_cs(void) 279static void __exit exit_fdomain_cs(void)
322{ 280{
323 pcmcia_unregister_driver(&fdomain_cs_driver); 281 pcmcia_unregister_driver(&fdomain_cs_driver);
324 BUG_ON(dev_list != NULL);
325} 282}
326 283
327module_init(init_fdomain_cs); 284module_init(init_fdomain_cs);
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c
index 050ea13ff80b..9e3ab3fd5355 100644
--- a/drivers/scsi/pcmcia/nsp_cs.c
+++ b/drivers/scsi/pcmcia/nsp_cs.c
@@ -104,9 +104,6 @@ static struct scsi_host_template nsp_driver_template = {
104#endif 104#endif
105}; 105};
106 106
107static dev_link_t *dev_list = NULL;
108static dev_info_t dev_info = {"nsp_cs"};
109
110static nsp_hw_data nsp_data_base; /* attach <-> detect glue */ 107static nsp_hw_data nsp_data_base; /* attach <-> detect glue */
111 108
112 109
@@ -1596,19 +1593,17 @@ static int nsp_eh_host_reset(Scsi_Cmnd *SCpnt)
1596 configure the card at this point -- we wait until we receive a 1593 configure the card at this point -- we wait until we receive a
1597 card insertion event. 1594 card insertion event.
1598======================================================================*/ 1595======================================================================*/
1599static dev_link_t *nsp_cs_attach(void) 1596static int nsp_cs_attach(struct pcmcia_device *p_dev)
1600{ 1597{
1601 scsi_info_t *info; 1598 scsi_info_t *info;
1602 client_reg_t client_reg;
1603 dev_link_t *link; 1599 dev_link_t *link;
1604 int ret;
1605 nsp_hw_data *data = &nsp_data_base; 1600 nsp_hw_data *data = &nsp_data_base;
1606 1601
1607 nsp_dbg(NSP_DEBUG_INIT, "in"); 1602 nsp_dbg(NSP_DEBUG_INIT, "in");
1608 1603
1609 /* Create new SCSI device */ 1604 /* Create new SCSI device */
1610 info = kmalloc(sizeof(*info), GFP_KERNEL); 1605 info = kmalloc(sizeof(*info), GFP_KERNEL);
1611 if (info == NULL) { return NULL; } 1606 if (info == NULL) { return -ENOMEM; }
1612 memset(info, 0, sizeof(*info)); 1607 memset(info, 0, sizeof(*info));
1613 link = &info->link; 1608 link = &info->link;
1614 link->priv = info; 1609 link->priv = info;
@@ -1636,23 +1631,14 @@ static dev_link_t *nsp_cs_attach(void)
1636 link->conf.IntType = INT_MEMORY_AND_IO; 1631 link->conf.IntType = INT_MEMORY_AND_IO;
1637 link->conf.Present = PRESENT_OPTION; 1632 link->conf.Present = PRESENT_OPTION;
1638 1633
1634 link->handle = p_dev;
1635 p_dev->instance = link;
1639 1636
1640 /* Register with Card Services */ 1637 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
1641 link->next = dev_list; 1638 nsp_cs_config(link);
1642 dev_list = link;
1643 client_reg.dev_info = &dev_info;
1644 client_reg.Version = 0x0210;
1645 client_reg.event_callback_args.client_data = link;
1646 ret = pcmcia_register_client(&link->handle, &client_reg);
1647 if (ret != CS_SUCCESS) {
1648 cs_error(link->handle, RegisterClient, ret);
1649 nsp_cs_detach(link);
1650 return NULL;
1651 }
1652
1653 1639
1654 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link); 1640 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
1655 return link; 1641 return 0;
1656} /* nsp_cs_attach */ 1642} /* nsp_cs_attach */
1657 1643
1658 1644
@@ -1662,35 +1648,19 @@ static dev_link_t *nsp_cs_attach(void)
1662 structures are freed. Otherwise, the structures will be freed 1648 structures are freed. Otherwise, the structures will be freed
1663 when the device is released. 1649 when the device is released.
1664======================================================================*/ 1650======================================================================*/
1665static void nsp_cs_detach(dev_link_t *link) 1651static void nsp_cs_detach(struct pcmcia_device *p_dev)
1666{ 1652{
1667 dev_link_t **linkp; 1653 dev_link_t *link = dev_to_instance(p_dev);
1668 1654
1669 nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link); 1655 nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link);
1670 1656
1671 /* Locate device structure */ 1657 if (link->state & DEV_CONFIG) {
1672 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) { 1658 ((scsi_info_t *)link->priv)->stop = 1;
1673 if (*linkp == link) {
1674 break;
1675 }
1676 }
1677 if (*linkp == NULL) {
1678 return;
1679 }
1680
1681 if (link->state & DEV_CONFIG)
1682 nsp_cs_release(link); 1659 nsp_cs_release(link);
1683
1684 /* Break the link with Card Services */
1685 if (link->handle) {
1686 pcmcia_deregister_client(link->handle);
1687 } 1660 }
1688 1661
1689 /* Unlink device structure, free bits */
1690 *linkp = link->next;
1691 kfree(link->priv); 1662 kfree(link->priv);
1692 link->priv = NULL; 1663 link->priv = NULL;
1693
1694} /* nsp_cs_detach */ 1664} /* nsp_cs_detach */
1695 1665
1696 1666
@@ -2021,99 +1991,58 @@ static void nsp_cs_release(dev_link_t *link)
2021#endif 1991#endif
2022} /* nsp_cs_release */ 1992} /* nsp_cs_release */
2023 1993
2024/*====================================================================== 1994static int nsp_cs_suspend(struct pcmcia_device *dev)
2025
2026 The card status event handler. Mostly, this schedules other
2027 stuff to run after an event is received. A CARD_REMOVAL event
2028 also sets some flags to discourage the net drivers from trying
2029 to talk to the card any more.
2030
2031 When a CARD_REMOVAL event is received, we immediately set a flag
2032 to block future accesses to this device. All the functions that
2033 actually access the device should check this flag to make sure
2034 the card is still present.
2035
2036======================================================================*/
2037static int nsp_cs_event(event_t event,
2038 int priority,
2039 event_callback_args_t *args)
2040{ 1995{
2041 dev_link_t *link = args->client_data; 1996 dev_link_t *link = dev_to_instance(dev);
2042 scsi_info_t *info = link->priv; 1997 scsi_info_t *info = link->priv;
2043 nsp_hw_data *data; 1998 nsp_hw_data *data;
2044 1999
2045 nsp_dbg(NSP_DEBUG_INIT, "in, event=0x%08x", event); 2000 link->state |= DEV_SUSPEND;
2046 2001
2047 switch (event) { 2002 nsp_dbg(NSP_DEBUG_INIT, "event: suspend");
2048 case CS_EVENT_CARD_REMOVAL:
2049 nsp_dbg(NSP_DEBUG_INIT, "event: remove");
2050 link->state &= ~DEV_PRESENT;
2051 if (link->state & DEV_CONFIG) {
2052 ((scsi_info_t *)link->priv)->stop = 1;
2053 nsp_cs_release(link);
2054 }
2055 break;
2056 2003
2057 case CS_EVENT_CARD_INSERTION: 2004 if (info->host != NULL) {
2058 nsp_dbg(NSP_DEBUG_INIT, "event: insert"); 2005 nsp_msg(KERN_INFO, "clear SDTR status");
2059 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
2060#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68))
2061 info->bus = args->bus;
2062#endif
2063 nsp_cs_config(link);
2064 break;
2065 2006
2066 case CS_EVENT_PM_SUSPEND: 2007 data = (nsp_hw_data *)info->host->hostdata;
2067 nsp_dbg(NSP_DEBUG_INIT, "event: suspend");
2068 link->state |= DEV_SUSPEND;
2069 /* Fall through... */
2070 case CS_EVENT_RESET_PHYSICAL:
2071 /* Mark the device as stopped, to block IO until later */
2072 nsp_dbg(NSP_DEBUG_INIT, "event: reset physical");
2073 2008
2074 if (info->host != NULL) { 2009 nsphw_init_sync(data);
2075 nsp_msg(KERN_INFO, "clear SDTR status"); 2010 }
2076 2011
2077 data = (nsp_hw_data *)info->host->hostdata; 2012 info->stop = 1;
2078 2013
2079 nsphw_init_sync(data); 2014 if (link->state & DEV_CONFIG)
2080 } 2015 pcmcia_release_configuration(link->handle);
2081 2016
2082 info->stop = 1; 2017 return 0;
2083 if (link->state & DEV_CONFIG) { 2018}
2084 pcmcia_release_configuration(link->handle);
2085 }
2086 break;
2087 2019
2088 case CS_EVENT_PM_RESUME: 2020static int nsp_cs_resume(struct pcmcia_device *dev)
2089 nsp_dbg(NSP_DEBUG_INIT, "event: resume"); 2021{
2090 link->state &= ~DEV_SUSPEND; 2022 dev_link_t *link = dev_to_instance(dev);
2091 /* Fall through... */ 2023 scsi_info_t *info = link->priv;
2092 case CS_EVENT_CARD_RESET: 2024 nsp_hw_data *data;
2093 nsp_dbg(NSP_DEBUG_INIT, "event: reset");
2094 if (link->state & DEV_CONFIG) {
2095 pcmcia_request_configuration(link->handle, &link->conf);
2096 }
2097 info->stop = 0;
2098 2025
2099 if (info->host != NULL) { 2026 nsp_dbg(NSP_DEBUG_INIT, "event: resume");
2100 nsp_msg(KERN_INFO, "reset host and bus");
2101 2027
2102 data = (nsp_hw_data *)info->host->hostdata; 2028 link->state &= ~DEV_SUSPEND;
2103 2029
2104 nsphw_init (data); 2030 if (link->state & DEV_CONFIG)
2105 nsp_bus_reset(data); 2031 pcmcia_request_configuration(link->handle, &link->conf);
2106 }
2107 2032
2108 break; 2033 info->stop = 0;
2109 2034
2110 default: 2035 if (info->host != NULL) {
2111 nsp_dbg(NSP_DEBUG_INIT, "event: unknown"); 2036 nsp_msg(KERN_INFO, "reset host and bus");
2112 break; 2037
2038 data = (nsp_hw_data *)info->host->hostdata;
2039
2040 nsphw_init (data);
2041 nsp_bus_reset(data);
2113 } 2042 }
2114 nsp_dbg(NSP_DEBUG_INIT, "end"); 2043
2115 return 0; 2044 return 0;
2116} /* nsp_cs_event */ 2045}
2117 2046
2118/*======================================================================* 2047/*======================================================================*
2119 * module entry point 2048 * module entry point
@@ -2136,10 +2065,11 @@ static struct pcmcia_driver nsp_driver = {
2136 .drv = { 2065 .drv = {
2137 .name = "nsp_cs", 2066 .name = "nsp_cs",
2138 }, 2067 },
2139 .attach = nsp_cs_attach, 2068 .probe = nsp_cs_attach,
2140 .event = nsp_cs_event, 2069 .remove = nsp_cs_detach,
2141 .detach = nsp_cs_detach,
2142 .id_table = nsp_cs_ids, 2070 .id_table = nsp_cs_ids,
2071 .suspend = nsp_cs_suspend,
2072 .resume = nsp_cs_resume,
2143}; 2073};
2144#endif 2074#endif
2145 2075
@@ -2171,7 +2101,6 @@ static void __exit nsp_cs_exit(void)
2171 2101
2172#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68)) 2102#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))
2173 pcmcia_unregister_driver(&nsp_driver); 2103 pcmcia_unregister_driver(&nsp_driver);
2174 BUG_ON(dev_list != NULL);
2175#else 2104#else
2176 unregister_pcmcia_driver(&dev_info); 2105 unregister_pcmcia_driver(&dev_info);
2177 /* XXX: this really needs to move into generic code.. */ 2106 /* XXX: this really needs to move into generic code.. */
diff --git a/drivers/scsi/pcmcia/nsp_cs.h b/drivers/scsi/pcmcia/nsp_cs.h
index f8b943082717..b66b140a745e 100644
--- a/drivers/scsi/pcmcia/nsp_cs.h
+++ b/drivers/scsi/pcmcia/nsp_cs.h
@@ -296,11 +296,9 @@ typedef struct _nsp_hw_data {
296 */ 296 */
297 297
298/* Card service functions */ 298/* Card service functions */
299static dev_link_t *nsp_cs_attach (void); 299static void nsp_cs_detach (struct pcmcia_device *p_dev);
300static void nsp_cs_detach (dev_link_t *link);
301static void nsp_cs_release(dev_link_t *link); 300static void nsp_cs_release(dev_link_t *link);
302static void nsp_cs_config (dev_link_t *link); 301static void nsp_cs_config (dev_link_t *link);
303static int nsp_cs_event (event_t event, int priority, event_callback_args_t *args);
304 302
305/* Linux SCSI subsystem specific functions */ 303/* Linux SCSI subsystem specific functions */
306static struct Scsi_Host *nsp_detect (struct scsi_host_template *sht); 304static struct Scsi_Host *nsp_detect (struct scsi_host_template *sht);
diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c
index bb091a45a880..dce7e687fd4a 100644
--- a/drivers/scsi/pcmcia/qlogic_stub.c
+++ b/drivers/scsi/pcmcia/qlogic_stub.c
@@ -98,15 +98,8 @@ typedef struct scsi_info_t {
98} scsi_info_t; 98} scsi_info_t;
99 99
100static void qlogic_release(dev_link_t *link); 100static void qlogic_release(dev_link_t *link);
101static int qlogic_event(event_t event, int priority, event_callback_args_t * args); 101static void qlogic_detach(struct pcmcia_device *p_dev);
102 102static void qlogic_config(dev_link_t * link);
103static dev_link_t *qlogic_attach(void);
104static void qlogic_detach(dev_link_t *);
105
106
107static dev_link_t *dev_list = NULL;
108
109static dev_info_t dev_info = "qlogic_cs";
110 103
111static struct Scsi_Host *qlogic_detect(struct scsi_host_template *host, 104static struct Scsi_Host *qlogic_detect(struct scsi_host_template *host,
112 dev_link_t *link, int qbase, int qlirq) 105 dev_link_t *link, int qbase, int qlirq)
@@ -163,19 +156,17 @@ free_scsi_host:
163err: 156err:
164 return NULL; 157 return NULL;
165} 158}
166static dev_link_t *qlogic_attach(void) 159static int qlogic_attach(struct pcmcia_device *p_dev)
167{ 160{
168 scsi_info_t *info; 161 scsi_info_t *info;
169 client_reg_t client_reg;
170 dev_link_t *link; 162 dev_link_t *link;
171 int ret;
172 163
173 DEBUG(0, "qlogic_attach()\n"); 164 DEBUG(0, "qlogic_attach()\n");
174 165
175 /* Create new SCSI device */ 166 /* Create new SCSI device */
176 info = kmalloc(sizeof(*info), GFP_KERNEL); 167 info = kmalloc(sizeof(*info), GFP_KERNEL);
177 if (!info) 168 if (!info)
178 return NULL; 169 return -ENOMEM;
179 memset(info, 0, sizeof(*info)); 170 memset(info, 0, sizeof(*info));
180 link = &info->link; 171 link = &info->link;
181 link->priv = info; 172 link->priv = info;
@@ -189,45 +180,26 @@ static dev_link_t *qlogic_attach(void)
189 link->conf.IntType = INT_MEMORY_AND_IO; 180 link->conf.IntType = INT_MEMORY_AND_IO;
190 link->conf.Present = PRESENT_OPTION; 181 link->conf.Present = PRESENT_OPTION;
191 182
192 /* Register with Card Services */ 183 link->handle = p_dev;
193 link->next = dev_list; 184 p_dev->instance = link;
194 dev_list = link;
195 client_reg.dev_info = &dev_info;
196 client_reg.Version = 0x0210;
197 client_reg.event_callback_args.client_data = link;
198 ret = pcmcia_register_client(&link->handle, &client_reg);
199 if (ret != 0) {
200 cs_error(link->handle, RegisterClient, ret);
201 qlogic_detach(link);
202 return NULL;
203 }
204 185
205 return link; 186 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
187 qlogic_config(link);
188
189 return 0;
206} /* qlogic_attach */ 190} /* qlogic_attach */
207 191
208/*====================================================================*/ 192/*====================================================================*/
209 193
210static void qlogic_detach(dev_link_t * link) 194static void qlogic_detach(struct pcmcia_device *p_dev)
211{ 195{
212 dev_link_t **linkp; 196 dev_link_t *link = dev_to_instance(p_dev);
213 197
214 DEBUG(0, "qlogic_detach(0x%p)\n", link); 198 DEBUG(0, "qlogic_detach(0x%p)\n", link);
215 199
216 /* Locate device structure */
217 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
218 if (*linkp == link)
219 break;
220 if (*linkp == NULL)
221 return;
222
223 if (link->state & DEV_CONFIG) 200 if (link->state & DEV_CONFIG)
224 qlogic_release(link); 201 qlogic_release(link);
225 202
226 if (link->handle)
227 pcmcia_deregister_client(link->handle);
228
229 /* Unlink device structure, free bits */
230 *linkp = link->next;
231 kfree(link->priv); 203 kfree(link->priv);
232 204
233} /* qlogic_detach */ 205} /* qlogic_detach */
@@ -349,48 +321,39 @@ static void qlogic_release(dev_link_t *link)
349 321
350/*====================================================================*/ 322/*====================================================================*/
351 323
352static int qlogic_event(event_t event, int priority, event_callback_args_t * args) 324static int qlogic_suspend(struct pcmcia_device *dev)
353{ 325{
354 dev_link_t *link = args->client_data; 326 dev_link_t *link = dev_to_instance(dev);
355 327
356 DEBUG(1, "qlogic_event(0x%06x)\n", event); 328 link->state |= DEV_SUSPEND;
357 329 if (link->state & DEV_CONFIG)
358 switch (event) { 330 pcmcia_release_configuration(link->handle);
359 case CS_EVENT_CARD_REMOVAL: 331
360 link->state &= ~DEV_PRESENT; 332 return 0;
361 if (link->state & DEV_CONFIG) 333}
362 qlogic_release(link); 334
363 break; 335static int qlogic_resume(struct pcmcia_device *dev)
364 case CS_EVENT_CARD_INSERTION: 336{
365 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 337 dev_link_t *link = dev_to_instance(dev);
366 qlogic_config(link); 338
367 break; 339 link->state &= ~DEV_SUSPEND;
368 case CS_EVENT_PM_SUSPEND: 340 if (link->state & DEV_CONFIG) {
369 link->state |= DEV_SUSPEND; 341 scsi_info_t *info = link->priv;
370 /* Fall through... */ 342
371 case CS_EVENT_RESET_PHYSICAL: 343 pcmcia_request_configuration(link->handle, &link->conf);
372 if (link->state & DEV_CONFIG) 344 if ((info->manf_id == MANFID_MACNICA) ||
373 pcmcia_release_configuration(link->handle); 345 (info->manf_id == MANFID_PIONEER) ||
374 break; 346 (info->manf_id == 0x0098)) {
375 case CS_EVENT_PM_RESUME: 347 outb(0x80, link->io.BasePort1 + 0xd);
376 link->state &= ~DEV_SUSPEND; 348 outb(0x24, link->io.BasePort1 + 0x9);
377 /* Fall through... */ 349 outb(0x04, link->io.BasePort1 + 0xd);
378 case CS_EVENT_CARD_RESET:
379 if (link->state & DEV_CONFIG) {
380 scsi_info_t *info = link->priv;
381 pcmcia_request_configuration(link->handle, &link->conf);
382 if ((info->manf_id == MANFID_MACNICA) || (info->manf_id == MANFID_PIONEER) || (info->manf_id == 0x0098)) {
383 outb(0x80, link->io.BasePort1 + 0xd);
384 outb(0x24, link->io.BasePort1 + 0x9);
385 outb(0x04, link->io.BasePort1 + 0xd);
386 }
387 /* Ugggglllyyyy!!! */
388 qlogicfas408_bus_reset(NULL);
389 } 350 }
390 break; 351 /* Ugggglllyyyy!!! */
352 qlogicfas408_bus_reset(NULL);
391 } 353 }
354
392 return 0; 355 return 0;
393} /* qlogic_event */ 356}
394 357
395static struct pcmcia_device_id qlogic_ids[] = { 358static struct pcmcia_device_id qlogic_ids[] = {
396 PCMCIA_DEVICE_PROD_ID12("EIger Labs", "PCMCIA-to-SCSI Adapter", 0x88395fa7, 0x33b7a5e6), 359 PCMCIA_DEVICE_PROD_ID12("EIger Labs", "PCMCIA-to-SCSI Adapter", 0x88395fa7, 0x33b7a5e6),
@@ -419,10 +382,11 @@ static struct pcmcia_driver qlogic_cs_driver = {
419 .drv = { 382 .drv = {
420 .name = "qlogic_cs", 383 .name = "qlogic_cs",
421 }, 384 },
422 .attach = qlogic_attach, 385 .probe = qlogic_attach,
423 .event = qlogic_event, 386 .remove = qlogic_detach,
424 .detach = qlogic_detach,
425 .id_table = qlogic_ids, 387 .id_table = qlogic_ids,
388 .suspend = qlogic_suspend,
389 .resume = qlogic_resume,
426}; 390};
427 391
428static int __init init_qlogic_cs(void) 392static int __init init_qlogic_cs(void)
@@ -433,7 +397,6 @@ static int __init init_qlogic_cs(void)
433static void __exit exit_qlogic_cs(void) 397static void __exit exit_qlogic_cs(void)
434{ 398{
435 pcmcia_unregister_driver(&qlogic_cs_driver); 399 pcmcia_unregister_driver(&qlogic_cs_driver);
436 BUG_ON(dev_list != NULL);
437} 400}
438 401
439MODULE_AUTHOR("Tom Zerucha, Michael Griffith"); 402MODULE_AUTHOR("Tom Zerucha, Michael Griffith");
diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c
index 98b64b2aa8ee..3a4dd6f5b81f 100644
--- a/drivers/scsi/pcmcia/sym53c500_cs.c
+++ b/drivers/scsi/pcmcia/sym53c500_cs.c
@@ -228,15 +228,6 @@ enum Phase {
228 228
229/* ================================================================== */ 229/* ================================================================== */
230 230
231/*
232* Global (within this module) variables other than
233* sym53c500_driver_template (the scsi_host_template).
234*/
235static dev_link_t *dev_list;
236static dev_info_t dev_info = "sym53c500_cs";
237
238/* ================================================================== */
239
240static void 231static void
241chip_init(int io_port) 232chip_init(int io_port)
242{ 233{
@@ -872,96 +863,70 @@ cs_failed:
872 return; 863 return;
873} /* SYM53C500_config */ 864} /* SYM53C500_config */
874 865
875static int 866static int sym53c500_suspend(struct pcmcia_device *dev)
876SYM53C500_event(event_t event, int priority, event_callback_args_t *args)
877{ 867{
878 dev_link_t *link = args->client_data; 868 dev_link_t *link = dev_to_instance(dev);
879 struct scsi_info_t *info = link->priv;
880 869
881 DEBUG(1, "SYM53C500_event(0x%06x)\n", event); 870 link->state |= DEV_SUSPEND;
871 if (link->state & DEV_CONFIG)
872 pcmcia_release_configuration(link->handle);
882 873
883 switch (event) { 874 return 0;
884 case CS_EVENT_CARD_REMOVAL: 875}
885 link->state &= ~DEV_PRESENT; 876
886 if (link->state & DEV_CONFIG) 877static int sym53c500_resume(struct pcmcia_device *dev)
887 SYM53C500_release(link); 878{
888 break; 879 dev_link_t *link = dev_to_instance(dev);
889 case CS_EVENT_CARD_INSERTION: 880 struct scsi_info_t *info = link->priv;
890 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 881
891 SYM53C500_config(link); 882 link->state &= ~DEV_SUSPEND;
892 break; 883 if (link->state & DEV_CONFIG) {
893 case CS_EVENT_PM_SUSPEND: 884 pcmcia_request_configuration(link->handle, &link->conf);
894 link->state |= DEV_SUSPEND; 885
895 /* Fall through... */ 886 /* See earlier comment about manufacturer IDs. */
896 case CS_EVENT_RESET_PHYSICAL: 887 if ((info->manf_id == MANFID_MACNICA) ||
897 if (link->state & DEV_CONFIG) 888 (info->manf_id == MANFID_PIONEER) ||
898 pcmcia_release_configuration(link->handle); 889 (info->manf_id == 0x0098)) {
899 break; 890 outb(0x80, link->io.BasePort1 + 0xd);
900 case CS_EVENT_PM_RESUME: 891 outb(0x24, link->io.BasePort1 + 0x9);
901 link->state &= ~DEV_SUSPEND; 892 outb(0x04, link->io.BasePort1 + 0xd);
902 /* Fall through... */
903 case CS_EVENT_CARD_RESET:
904 if (link->state & DEV_CONFIG) {
905 pcmcia_request_configuration(link->handle, &link->conf);
906 /* See earlier comment about manufacturer IDs. */
907 if ((info->manf_id == MANFID_MACNICA) ||
908 (info->manf_id == MANFID_PIONEER) ||
909 (info->manf_id == 0x0098)) {
910 outb(0x80, link->io.BasePort1 + 0xd);
911 outb(0x24, link->io.BasePort1 + 0x9);
912 outb(0x04, link->io.BasePort1 + 0xd);
913 }
914 /*
915 * If things don't work after a "resume",
916 * this is a good place to start looking.
917 */
918 SYM53C500_int_host_reset(link->io.BasePort1);
919 } 893 }
920 break; 894 /*
895 * If things don't work after a "resume",
896 * this is a good place to start looking.
897 */
898 SYM53C500_int_host_reset(link->io.BasePort1);
921 } 899 }
900
922 return 0; 901 return 0;
923} /* SYM53C500_event */ 902}
924 903
925static void 904static void
926SYM53C500_detach(dev_link_t *link) 905SYM53C500_detach(struct pcmcia_device *p_dev)
927{ 906{
928 dev_link_t **linkp; 907 dev_link_t *link = dev_to_instance(p_dev);
929 908
930 DEBUG(0, "SYM53C500_detach(0x%p)\n", link); 909 DEBUG(0, "SYM53C500_detach(0x%p)\n", link);
931 910
932 /* Locate device structure */
933 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
934 if (*linkp == link)
935 break;
936 if (*linkp == NULL)
937 return;
938
939 if (link->state & DEV_CONFIG) 911 if (link->state & DEV_CONFIG)
940 SYM53C500_release(link); 912 SYM53C500_release(link);
941 913
942 if (link->handle)
943 pcmcia_deregister_client(link->handle);
944
945 /* Unlink device structure, free bits. */
946 *linkp = link->next;
947 kfree(link->priv); 914 kfree(link->priv);
948 link->priv = NULL; 915 link->priv = NULL;
949} /* SYM53C500_detach */ 916} /* SYM53C500_detach */
950 917
951static dev_link_t * 918static int
952SYM53C500_attach(void) 919SYM53C500_attach(struct pcmcia_device *p_dev)
953{ 920{
954 struct scsi_info_t *info; 921 struct scsi_info_t *info;
955 client_reg_t client_reg;
956 dev_link_t *link; 922 dev_link_t *link;
957 int ret;
958 923
959 DEBUG(0, "SYM53C500_attach()\n"); 924 DEBUG(0, "SYM53C500_attach()\n");
960 925
961 /* Create new SCSI device */ 926 /* Create new SCSI device */
962 info = kmalloc(sizeof(*info), GFP_KERNEL); 927 info = kmalloc(sizeof(*info), GFP_KERNEL);
963 if (!info) 928 if (!info)
964 return NULL; 929 return -ENOMEM;
965 memset(info, 0, sizeof(*info)); 930 memset(info, 0, sizeof(*info));
966 link = &info->link; 931 link = &info->link;
967 link->priv = info; 932 link->priv = info;
@@ -975,20 +940,13 @@ SYM53C500_attach(void)
975 link->conf.IntType = INT_MEMORY_AND_IO; 940 link->conf.IntType = INT_MEMORY_AND_IO;
976 link->conf.Present = PRESENT_OPTION; 941 link->conf.Present = PRESENT_OPTION;
977 942
978 /* Register with Card Services */ 943 link->handle = p_dev;
979 link->next = dev_list; 944 p_dev->instance = link;
980 dev_list = link; 945
981 client_reg.dev_info = &dev_info; 946 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
982 client_reg.Version = 0x0210; 947 SYM53C500_config(link);
983 client_reg.event_callback_args.client_data = link;
984 ret = pcmcia_register_client(&link->handle, &client_reg);
985 if (ret != 0) {
986 cs_error(link->handle, RegisterClient, ret);
987 SYM53C500_detach(link);
988 return NULL;
989 }
990 948
991 return link; 949 return 0;
992} /* SYM53C500_attach */ 950} /* SYM53C500_attach */
993 951
994MODULE_AUTHOR("Bob Tracy <rct@frus.com>"); 952MODULE_AUTHOR("Bob Tracy <rct@frus.com>");
@@ -1008,10 +966,11 @@ static struct pcmcia_driver sym53c500_cs_driver = {
1008 .drv = { 966 .drv = {
1009 .name = "sym53c500_cs", 967 .name = "sym53c500_cs",
1010 }, 968 },
1011 .attach = SYM53C500_attach, 969 .probe = SYM53C500_attach,
1012 .event = SYM53C500_event, 970 .remove = SYM53C500_detach,
1013 .detach = SYM53C500_detach,
1014 .id_table = sym53c500_ids, 971 .id_table = sym53c500_ids,
972 .suspend = sym53c500_suspend,
973 .resume = sym53c500_resume,
1015}; 974};
1016 975
1017static int __init 976static int __init
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index 7ce0c7e66d37..96969cb960a9 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -114,15 +114,7 @@ struct serial_cfg_mem {
114 114
115 115
116static void serial_config(dev_link_t * link); 116static void serial_config(dev_link_t * link);
117static int serial_event(event_t event, int priority,
118 event_callback_args_t * args);
119 117
120static dev_info_t dev_info = "serial_cs";
121
122static dev_link_t *serial_attach(void);
123static void serial_detach(dev_link_t *);
124
125static dev_link_t *dev_list = NULL;
126 118
127/*====================================================================== 119/*======================================================================
128 120
@@ -159,8 +151,9 @@ static void serial_remove(dev_link_t *link)
159 } 151 }
160} 152}
161 153
162static void serial_suspend(dev_link_t *link) 154static int serial_suspend(struct pcmcia_device *dev)
163{ 155{
156 dev_link_t *link = dev_to_instance(dev);
164 link->state |= DEV_SUSPEND; 157 link->state |= DEV_SUSPEND;
165 158
166 if (link->state & DEV_CONFIG) { 159 if (link->state & DEV_CONFIG) {
@@ -173,10 +166,13 @@ static void serial_suspend(dev_link_t *link)
173 if (!info->slave) 166 if (!info->slave)
174 pcmcia_release_configuration(link->handle); 167 pcmcia_release_configuration(link->handle);
175 } 168 }
169
170 return 0;
176} 171}
177 172
178static void serial_resume(dev_link_t *link) 173static int serial_resume(struct pcmcia_device *dev)
179{ 174{
175 dev_link_t *link = dev_to_instance(dev);
180 link->state &= ~DEV_SUSPEND; 176 link->state &= ~DEV_SUSPEND;
181 177
182 if (DEV_OK(link)) { 178 if (DEV_OK(link)) {
@@ -189,6 +185,8 @@ static void serial_resume(dev_link_t *link)
189 for (i = 0; i < info->ndev; i++) 185 for (i = 0; i < info->ndev; i++)
190 serial8250_resume_port(info->line[i]); 186 serial8250_resume_port(info->line[i]);
191 } 187 }
188
189 return 0;
192} 190}
193 191
194/*====================================================================== 192/*======================================================================
@@ -199,19 +197,17 @@ static void serial_resume(dev_link_t *link)
199 197
200======================================================================*/ 198======================================================================*/
201 199
202static dev_link_t *serial_attach(void) 200static int serial_probe(struct pcmcia_device *p_dev)
203{ 201{
204 struct serial_info *info; 202 struct serial_info *info;
205 client_reg_t client_reg;
206 dev_link_t *link; 203 dev_link_t *link;
207 int ret;
208 204
209 DEBUG(0, "serial_attach()\n"); 205 DEBUG(0, "serial_attach()\n");
210 206
211 /* Create new serial device */ 207 /* Create new serial device */
212 info = kmalloc(sizeof (*info), GFP_KERNEL); 208 info = kmalloc(sizeof (*info), GFP_KERNEL);
213 if (!info) 209 if (!info)
214 return NULL; 210 return -ENOMEM;
215 memset(info, 0, sizeof (*info)); 211 memset(info, 0, sizeof (*info));
216 link = &info->link; 212 link = &info->link;
217 link->priv = info; 213 link->priv = info;
@@ -227,20 +223,12 @@ static dev_link_t *serial_attach(void)
227 } 223 }
228 link->conf.IntType = INT_MEMORY_AND_IO; 224 link->conf.IntType = INT_MEMORY_AND_IO;
229 225
230 /* Register with Card Services */ 226 link->handle = p_dev;
231 link->next = dev_list; 227 p_dev->instance = link;
232 dev_list = link; 228 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
233 client_reg.dev_info = &dev_info; 229 serial_config(link);
234 client_reg.Version = 0x0210;
235 client_reg.event_callback_args.client_data = link;
236 ret = pcmcia_register_client(&link->handle, &client_reg);
237 if (ret != CS_SUCCESS) {
238 cs_error(link->handle, RegisterClient, ret);
239 serial_detach(link);
240 return NULL;
241 }
242 230
243 return link; 231 return 0;
244} 232}
245 233
246/*====================================================================== 234/*======================================================================
@@ -252,21 +240,13 @@ static dev_link_t *serial_attach(void)
252 240
253======================================================================*/ 241======================================================================*/
254 242
255static void serial_detach(dev_link_t * link) 243static void serial_detach(struct pcmcia_device *p_dev)
256{ 244{
245 dev_link_t *link = dev_to_instance(p_dev);
257 struct serial_info *info = link->priv; 246 struct serial_info *info = link->priv;
258 dev_link_t **linkp;
259 int ret;
260 247
261 DEBUG(0, "serial_detach(0x%p)\n", link); 248 DEBUG(0, "serial_detach(0x%p)\n", link);
262 249
263 /* Locate device structure */
264 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
265 if (*linkp == link)
266 break;
267 if (*linkp == NULL)
268 return;
269
270 /* 250 /*
271 * Ensure any outstanding scheduled tasks are completed. 251 * Ensure any outstanding scheduled tasks are completed.
272 */ 252 */
@@ -277,14 +257,7 @@ static void serial_detach(dev_link_t * link)
277 */ 257 */
278 serial_remove(link); 258 serial_remove(link);
279 259
280 if (link->handle) { 260 /* free bits */
281 ret = pcmcia_deregister_client(link->handle);
282 if (ret != CS_SUCCESS)
283 cs_error(link->handle, DeregisterClient, ret);
284 }
285
286 /* Unlink device structure, free bits */
287 *linkp = link->next;
288 kfree(info); 261 kfree(info);
289} 262}
290 263
@@ -718,54 +691,6 @@ void serial_config(dev_link_t * link)
718 kfree(cfg_mem); 691 kfree(cfg_mem);
719} 692}
720 693
721/*======================================================================
722
723 The card status event handler. Mostly, this schedules other
724 stuff to run after an event is received. A CARD_REMOVAL event
725 also sets some flags to discourage the serial drivers from
726 talking to the ports.
727
728======================================================================*/
729
730static int
731serial_event(event_t event, int priority, event_callback_args_t * args)
732{
733 dev_link_t *link = args->client_data;
734 struct serial_info *info = link->priv;
735
736 DEBUG(1, "serial_event(0x%06x)\n", event);
737
738 switch (event) {
739 case CS_EVENT_CARD_REMOVAL:
740 serial_remove(link);
741 break;
742
743 case CS_EVENT_CARD_INSERTION:
744 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
745 serial_config(link);
746 break;
747
748 case CS_EVENT_PM_SUSPEND:
749 serial_suspend(link);
750 break;
751
752 case CS_EVENT_RESET_PHYSICAL:
753 if ((link->state & DEV_CONFIG) && !info->slave)
754 pcmcia_release_configuration(link->handle);
755 break;
756
757 case CS_EVENT_PM_RESUME:
758 serial_resume(link);
759 break;
760
761 case CS_EVENT_CARD_RESET:
762 if (DEV_OK(link) && !info->slave)
763 pcmcia_request_configuration(link->handle, &link->conf);
764 break;
765 }
766 return 0;
767}
768
769static struct pcmcia_device_id serial_ids[] = { 694static struct pcmcia_device_id serial_ids[] = {
770 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0057, 0x0021), 695 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0057, 0x0021),
771 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0089, 0x110a), 696 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0089, 0x110a),
@@ -877,10 +802,11 @@ static struct pcmcia_driver serial_cs_driver = {
877 .drv = { 802 .drv = {
878 .name = "serial_cs", 803 .name = "serial_cs",
879 }, 804 },
880 .attach = serial_attach, 805 .probe = serial_probe,
881 .event = serial_event, 806 .remove = serial_detach,
882 .detach = serial_detach,
883 .id_table = serial_ids, 807 .id_table = serial_ids,
808 .suspend = serial_suspend,
809 .resume = serial_resume,
884}; 810};
885 811
886static int __init init_serial_cs(void) 812static int __init init_serial_cs(void)
@@ -891,7 +817,6 @@ static int __init init_serial_cs(void)
891static void __exit exit_serial_cs(void) 817static void __exit exit_serial_cs(void)
892{ 818{
893 pcmcia_unregister_driver(&serial_cs_driver); 819 pcmcia_unregister_driver(&serial_cs_driver);
894 BUG_ON(dev_list != NULL);
895} 820}
896 821
897module_init(init_serial_cs); 822module_init(init_serial_cs);
diff --git a/drivers/telephony/ixj_pcmcia.c b/drivers/telephony/ixj_pcmcia.c
index 57c0c6e3fbed..d3a7b0c3d38b 100644
--- a/drivers/telephony/ixj_pcmcia.c
+++ b/drivers/telephony/ixj_pcmcia.c
@@ -34,24 +34,19 @@ typedef struct ixj_info_t {
34 struct ixj *port; 34 struct ixj *port;
35} ixj_info_t; 35} ixj_info_t;
36 36
37static dev_link_t *ixj_attach(void); 37static void ixj_detach(struct pcmcia_device *p_dev);
38static void ixj_detach(dev_link_t *);
39static void ixj_config(dev_link_t * link); 38static void ixj_config(dev_link_t * link);
40static void ixj_cs_release(dev_link_t * link); 39static void ixj_cs_release(dev_link_t * link);
41static int ixj_event(event_t event, int priority, event_callback_args_t * args);
42static dev_info_t dev_info = "ixj_cs";
43static dev_link_t *dev_list = NULL;
44 40
45static dev_link_t *ixj_attach(void) 41static int ixj_attach(struct pcmcia_device *p_dev)
46{ 42{
47 client_reg_t client_reg;
48 dev_link_t *link; 43 dev_link_t *link;
49 int ret; 44
50 DEBUG(0, "ixj_attach()\n"); 45 DEBUG(0, "ixj_attach()\n");
51 /* Create new ixj device */ 46 /* Create new ixj device */
52 link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); 47 link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
53 if (!link) 48 if (!link)
54 return NULL; 49 return -ENOMEM;
55 memset(link, 0, sizeof(struct dev_link_t)); 50 memset(link, 0, sizeof(struct dev_link_t));
56 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; 51 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
57 link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; 52 link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
@@ -61,44 +56,29 @@ static dev_link_t *ixj_attach(void)
61 link->priv = kmalloc(sizeof(struct ixj_info_t), GFP_KERNEL); 56 link->priv = kmalloc(sizeof(struct ixj_info_t), GFP_KERNEL);
62 if (!link->priv) { 57 if (!link->priv) {
63 kfree(link); 58 kfree(link);
64 return NULL; 59 return -ENOMEM;
65 } 60 }
66 memset(link->priv, 0, sizeof(struct ixj_info_t)); 61 memset(link->priv, 0, sizeof(struct ixj_info_t));
67 /* Register with Card Services */ 62
68 link->next = dev_list; 63 link->handle = p_dev;
69 dev_list = link; 64 p_dev->instance = link;
70 client_reg.dev_info = &dev_info; 65
71 client_reg.Version = 0x0210; 66 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
72 client_reg.event_callback_args.client_data = link; 67 ixj_config(link);
73 ret = pcmcia_register_client(&link->handle, &client_reg); 68
74 if (ret != CS_SUCCESS) { 69 return 0;
75 cs_error(link->handle, RegisterClient, ret);
76 ixj_detach(link);
77 return NULL;
78 }
79 return link;
80} 70}
81 71
82static void ixj_detach(dev_link_t * link) 72static void ixj_detach(struct pcmcia_device *p_dev)
83{ 73{
84 dev_link_t **linkp; 74 dev_link_t *link = dev_to_instance(p_dev);
85 int ret; 75
86 DEBUG(0, "ixj_detach(0x%p)\n", link); 76 DEBUG(0, "ixj_detach(0x%p)\n", link);
87 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) 77
88 if (*linkp == link)
89 break;
90 if (*linkp == NULL)
91 return;
92 link->state &= ~DEV_RELEASE_PENDING; 78 link->state &= ~DEV_RELEASE_PENDING;
93 if (link->state & DEV_CONFIG) 79 if (link->state & DEV_CONFIG)
94 ixj_cs_release(link); 80 ixj_cs_release(link);
95 if (link->handle) { 81
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 */
101 *linkp = link->next;
102 kfree(link->priv); 82 kfree(link->priv);
103 kfree(link); 83 kfree(link);
104} 84}
@@ -255,37 +235,25 @@ static void ixj_cs_release(dev_link_t *link)
255 link->state &= ~DEV_CONFIG; 235 link->state &= ~DEV_CONFIG;
256} 236}
257 237
258static int ixj_event(event_t event, int priority, event_callback_args_t * args) 238static int ixj_suspend(struct pcmcia_device *dev)
259{ 239{
260 dev_link_t *link = args->client_data; 240 dev_link_t *link = dev_to_instance(dev);
261 DEBUG(1, "ixj_event(0x%06x)\n", event); 241
262 switch (event) { 242 link->state |= DEV_SUSPEND;
263 case CS_EVENT_CARD_REMOVAL: 243 if (link->state & DEV_CONFIG)
264 link->state &= ~DEV_PRESENT; 244 pcmcia_release_configuration(link->handle);
265 if (link->state & DEV_CONFIG) { 245
266 link->state |= DEV_RELEASE_PENDING; 246 return 0;
267 ixj_cs_release(link); 247}
268 } 248
269 break; 249static int ixj_resume(struct pcmcia_device *dev)
270 case CS_EVENT_CARD_INSERTION: 250{
271 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 251 dev_link_t *link = dev_to_instance(dev);
272 ixj_config(link); 252
273 break; 253 link->state &= ~DEV_SUSPEND;
274 case CS_EVENT_PM_SUSPEND: 254 if (DEV_OK(link))
275 link->state |= DEV_SUSPEND; 255 pcmcia_request_configuration(link->handle, &link->conf);
276 /* Fall through... */ 256
277 case CS_EVENT_RESET_PHYSICAL:
278 if (link->state & DEV_CONFIG)
279 pcmcia_release_configuration(link->handle);
280 break;
281 case CS_EVENT_PM_RESUME:
282 link->state &= ~DEV_SUSPEND;
283 /* Fall through... */
284 case CS_EVENT_CARD_RESET:
285 if (DEV_OK(link))
286 pcmcia_request_configuration(link->handle, &link->conf);
287 break;
288 }
289 return 0; 257 return 0;
290} 258}
291 259
@@ -300,10 +268,11 @@ static struct pcmcia_driver ixj_driver = {
300 .drv = { 268 .drv = {
301 .name = "ixj_cs", 269 .name = "ixj_cs",
302 }, 270 },
303 .attach = ixj_attach, 271 .probe = ixj_attach,
304 .event = ixj_event, 272 .remove = ixj_detach,
305 .detach = ixj_detach,
306 .id_table = ixj_ids, 273 .id_table = ixj_ids,
274 .suspend = ixj_suspend,
275 .resume = ixj_resume,
307}; 276};
308 277
309static int __init ixj_pcmcia_init(void) 278static int __init ixj_pcmcia_init(void)
@@ -314,7 +283,6 @@ static int __init ixj_pcmcia_init(void)
314static void ixj_pcmcia_exit(void) 283static void ixj_pcmcia_exit(void)
315{ 284{
316 pcmcia_unregister_driver(&ixj_driver); 285 pcmcia_unregister_driver(&ixj_driver);
317 BUG_ON(dev_list != NULL);
318} 286}
319 287
320module_init(ixj_pcmcia_init); 288module_init(ixj_pcmcia_init);
diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c
index 5056b7459994..466384d7c79f 100644
--- a/drivers/usb/host/sl811_cs.c
+++ b/drivers/usb/host/sl811_cs.c
@@ -66,13 +66,13 @@ module_param(pc_debug, int, 0644);
66 66
67static const char driver_name[DEV_NAME_LEN] = "sl811_cs"; 67static const char driver_name[DEV_NAME_LEN] = "sl811_cs";
68 68
69static dev_link_t *dev_list = NULL;
70
71typedef struct local_info_t { 69typedef struct local_info_t {
72 dev_link_t link; 70 dev_link_t link;
73 dev_node_t node; 71 dev_node_t node;
74} local_info_t; 72} local_info_t;
75 73
74static void sl811_cs_release(dev_link_t * link);
75
76/*====================================================================*/ 76/*====================================================================*/
77 77
78static void release_platform_dev(struct device * dev) 78static void release_platform_dev(struct device * dev)
@@ -138,26 +138,16 @@ static int sl811_hc_init(struct device *parent, ioaddr_t base_addr, int irq)
138 138
139/*====================================================================*/ 139/*====================================================================*/
140 140
141static void sl811_cs_detach(dev_link_t *link) 141static void sl811_cs_detach(struct pcmcia_device *p_dev)
142{ 142{
143 dev_link_t **linkp; 143 dev_link_t *link = dev_to_instance(p_dev);
144 144
145 DBG(0, "sl811_cs_detach(0x%p)\n", link); 145 DBG(0, "sl811_cs_detach(0x%p)\n", link);
146 146
147 /* Locate device structure */ 147 link->state &= ~DEV_PRESENT;
148 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) { 148 if (link->state & DEV_CONFIG)
149 if (*linkp == link) 149 sl811_cs_release(link);
150 break;
151 }
152 if (*linkp == NULL)
153 return;
154
155 /* Break the link with Card Services */
156 if (link->handle)
157 pcmcia_deregister_client(link->handle);
158 150
159 /* Unlink device structure, and free it */
160 *linkp = link->next;
161 /* This points to the parent local_info_t struct */ 151 /* This points to the parent local_info_t struct */
162 kfree(link->priv); 152 kfree(link->priv);
163} 153}
@@ -167,13 +157,6 @@ static void sl811_cs_release(dev_link_t * link)
167 157
168 DBG(0, "sl811_cs_release(0x%p)\n", link); 158 DBG(0, "sl811_cs_release(0x%p)\n", link);
169 159
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 */ 160 /* Unlink the device chain */
178 link->dev = NULL; 161 link->dev = NULL;
179 162
@@ -184,9 +167,6 @@ static void sl811_cs_release(dev_link_t * link)
184 if (link->irq.AssignedIRQ) 167 if (link->irq.AssignedIRQ)
185 pcmcia_release_irq(link->handle, &link->irq); 168 pcmcia_release_irq(link->handle, &link->irq);
186 link->state &= ~DEV_CONFIG; 169 link->state &= ~DEV_CONFIG;
187
188 if (link->state & DEV_STALE_LINK)
189 sl811_cs_detach(link);
190} 170}
191 171
192static void sl811_cs_config(dev_link_t *link) 172static void sl811_cs_config(dev_link_t *link)
@@ -323,55 +303,36 @@ cs_failed:
323 } 303 }
324} 304}
325 305
326static int 306static int sl811_suspend(struct pcmcia_device *dev)
327sl811_cs_event(event_t event, int priority, event_callback_args_t *args)
328{ 307{
329 dev_link_t *link = args->client_data; 308 dev_link_t *link = dev_to_instance(dev);
330 309
331 DBG(1, "sl811_cs_event(0x%06x)\n", event); 310 link->state |= DEV_SUSPEND;
311 if (link->state & DEV_CONFIG)
312 pcmcia_release_configuration(link->handle);
332 313
333 switch (event) { 314 return 0;
334 case CS_EVENT_CARD_REMOVAL: 315}
335 link->state &= ~DEV_PRESENT;
336 if (link->state & DEV_CONFIG)
337 sl811_cs_release(link);
338 break;
339 316
340 case CS_EVENT_CARD_INSERTION: 317static int sl811_resume(struct pcmcia_device *dev)
341 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 318{
342 sl811_cs_config(link); 319 dev_link_t *link = dev_to_instance(dev);
343 break;
344 320
345 case CS_EVENT_PM_SUSPEND: 321 link->state &= ~DEV_SUSPEND;
346 link->state |= DEV_SUSPEND; 322 if (link->state & DEV_CONFIG)
347 /* Fall through... */ 323 pcmcia_request_configuration(link->handle, &link->conf);
348 case CS_EVENT_RESET_PHYSICAL:
349 if (link->state & DEV_CONFIG)
350 pcmcia_release_configuration(link->handle);
351 break;
352 324
353 case CS_EVENT_PM_RESUME:
354 link->state &= ~DEV_SUSPEND;
355 /* Fall through... */
356 case CS_EVENT_CARD_RESET:
357 if (link->state & DEV_CONFIG)
358 pcmcia_request_configuration(link->handle, &link->conf);
359 DBG(0, "reset sl811-hcd here?\n");
360 break;
361 }
362 return 0; 325 return 0;
363} 326}
364 327
365static dev_link_t *sl811_cs_attach(void) 328static int sl811_cs_attach(struct pcmcia_device *p_dev)
366{ 329{
367 local_info_t *local; 330 local_info_t *local;
368 dev_link_t *link; 331 dev_link_t *link;
369 client_reg_t client_reg;
370 int ret;
371 332
372 local = kmalloc(sizeof(local_info_t), GFP_KERNEL); 333 local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
373 if (!local) 334 if (!local)
374 return NULL; 335 return -ENOMEM;
375 memset(local, 0, sizeof(local_info_t)); 336 memset(local, 0, sizeof(local_info_t));
376 link = &local->link; 337 link = &local->link;
377 link->priv = local; 338 link->priv = local;
@@ -385,21 +346,13 @@ static dev_link_t *sl811_cs_attach(void)
385 link->conf.Vcc = 33; 346 link->conf.Vcc = 33;
386 link->conf.IntType = INT_MEMORY_AND_IO; 347 link->conf.IntType = INT_MEMORY_AND_IO;
387 348
388 /* Register with Card Services */ 349 link->handle = p_dev;
389 link->next = dev_list; 350 p_dev->instance = link;
390 dev_list = link;
391 client_reg.dev_info = (dev_info_t *) &driver_name;
392 client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
393 client_reg.Version = 0x0210;
394 client_reg.event_callback_args.client_data = link;
395 ret = pcmcia_register_client(&link->handle, &client_reg);
396 if (ret != CS_SUCCESS) {
397 cs_error(link->handle, RegisterClient, ret);
398 sl811_cs_detach(link);
399 return NULL;
400 }
401 351
402 return link; 352 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
353 sl811_cs_config(link);
354
355 return 0;
403} 356}
404 357
405static struct pcmcia_device_id sl811_ids[] = { 358static struct pcmcia_device_id sl811_ids[] = {
@@ -413,10 +366,11 @@ static struct pcmcia_driver sl811_cs_driver = {
413 .drv = { 366 .drv = {
414 .name = (char *)driver_name, 367 .name = (char *)driver_name,
415 }, 368 },
416 .attach = sl811_cs_attach, 369 .probe = sl811_cs_attach,
417 .event = sl811_cs_event, 370 .remove = sl811_cs_detach,
418 .detach = sl811_cs_detach,
419 .id_table = sl811_ids, 371 .id_table = sl811_ids,
372 .suspend = sl811_suspend,
373 .resume = sl811_resume,
420}; 374};
421 375
422/*====================================================================*/ 376/*====================================================================*/
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 08edbfcfca58..3fefdb0cbf07 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -403,7 +403,7 @@ static struct {
403 { PCI_CHIP_MACH64GM, "3D RAGE XL (Mach64 GM, AGP)", 230, 83, 63, ATI_CHIP_264XL }, 403 { PCI_CHIP_MACH64GM, "3D RAGE XL (Mach64 GM, AGP)", 230, 83, 63, ATI_CHIP_264XL },
404 { PCI_CHIP_MACH64GN, "3D RAGE XL (Mach64 GN, AGP)", 230, 83, 63, ATI_CHIP_264XL }, 404 { PCI_CHIP_MACH64GN, "3D RAGE XL (Mach64 GN, AGP)", 230, 83, 63, ATI_CHIP_264XL },
405 { PCI_CHIP_MACH64GO, "3D RAGE XL (Mach64 GO, PCI-66/BGA)", 230, 83, 63, ATI_CHIP_264XL }, 405 { PCI_CHIP_MACH64GO, "3D RAGE XL (Mach64 GO, PCI-66/BGA)", 230, 83, 63, ATI_CHIP_264XL },
406 { PCI_CHIP_MACH64GR, "3D RAGE XL (Mach64 GR, PCI-33MHz)", 230, 83, 63, ATI_CHIP_264XL }, 406 { PCI_CHIP_MACH64GR, "3D RAGE XL (Mach64 GR, PCI-33MHz)", 235, 83, 63, ATI_CHIP_264XL | M64F_SDRAM_MAGIC_PLL },
407 { PCI_CHIP_MACH64GL, "3D RAGE XL (Mach64 GL, PCI)", 230, 83, 63, ATI_CHIP_264XL }, 407 { PCI_CHIP_MACH64GL, "3D RAGE XL (Mach64 GL, PCI)", 230, 83, 63, ATI_CHIP_264XL },
408 { PCI_CHIP_MACH64GS, "3D RAGE XL (Mach64 GS, PCI)", 230, 83, 63, ATI_CHIP_264XL }, 408 { PCI_CHIP_MACH64GS, "3D RAGE XL (Mach64 GS, PCI)", 230, 83, 63, ATI_CHIP_264XL },
409 409
diff --git a/include/linux/netfilter/nfnetlink_conntrack.h b/include/linux/netfilter/nfnetlink_conntrack.h
index 116fcaced909..668ec946c8e2 100644
--- a/include/linux/netfilter/nfnetlink_conntrack.h
+++ b/include/linux/netfilter/nfnetlink_conntrack.h
@@ -64,6 +64,9 @@ enum ctattr_l4proto {
64 CTA_PROTO_ICMP_ID, 64 CTA_PROTO_ICMP_ID,
65 CTA_PROTO_ICMP_TYPE, 65 CTA_PROTO_ICMP_TYPE,
66 CTA_PROTO_ICMP_CODE, 66 CTA_PROTO_ICMP_CODE,
67 CTA_PROTO_ICMPV6_ID,
68 CTA_PROTO_ICMPV6_TYPE,
69 CTA_PROTO_ICMPV6_CODE,
67 __CTA_PROTO_MAX 70 __CTA_PROTO_MAX
68}; 71};
69#define CTA_PROTO_MAX (__CTA_PROTO_MAX - 1) 72#define CTA_PROTO_MAX (__CTA_PROTO_MAX - 1)
@@ -128,6 +131,4 @@ enum ctattr_help {
128}; 131};
129#define CTA_HELP_MAX (__CTA_HELP_MAX - 1) 132#define CTA_HELP_MAX (__CTA_HELP_MAX - 1)
130 133
131#define CTA_HELP_MAXNAMESIZE 32
132
133#endif /* _IPCONNTRACK_NETLINK_H */ 134#endif /* _IPCONNTRACK_NETLINK_H */
diff --git a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h
index 2efc046d9e94..c163ba31aab7 100644
--- a/include/linux/netfilter_ipv6/ip6_tables.h
+++ b/include/linux/netfilter_ipv6/ip6_tables.h
@@ -474,7 +474,11 @@ extern unsigned int ip6t_do_table(struct sk_buff **pskb,
474extern int ip6t_ext_hdr(u8 nexthdr); 474extern int ip6t_ext_hdr(u8 nexthdr);
475/* find specified header and get offset to it */ 475/* find specified header and get offset to it */
476extern int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, 476extern int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
477 u8 target); 477 int target, unsigned short *fragoff);
478
479extern int ip6_masked_addrcmp(const struct in6_addr *addr1,
480 const struct in6_addr *mask,
481 const struct in6_addr *addr2);
478 482
479#define IP6T_ALIGN(s) (((s) + (__alignof__(struct ip6t_entry)-1)) & ~(__alignof__(struct ip6t_entry)-1)) 483#define IP6T_ALIGN(s) (((s) + (__alignof__(struct ip6t_entry)-1)) & ~(__alignof__(struct ip6t_entry)-1))
480 484
diff --git a/include/net/ip.h b/include/net/ip.h
index f7e7fd728b67..7bb5804847f2 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -317,7 +317,6 @@ enum ip_defrag_users
317 IP_DEFRAG_CALL_RA_CHAIN, 317 IP_DEFRAG_CALL_RA_CHAIN,
318 IP_DEFRAG_CONNTRACK_IN, 318 IP_DEFRAG_CONNTRACK_IN,
319 IP_DEFRAG_CONNTRACK_OUT, 319 IP_DEFRAG_CONNTRACK_OUT,
320 IP_DEFRAG_NAT_OUT,
321 IP_DEFRAG_VS_IN, 320 IP_DEFRAG_VS_IN,
322 IP_DEFRAG_VS_OUT, 321 IP_DEFRAG_VS_OUT,
323 IP_DEFRAG_VS_FWD 322 IP_DEFRAG_VS_FWD
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
index cc4825610795..64b82b74a650 100644
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -94,6 +94,9 @@ struct nf_conn
94 /* Current number of expected connections */ 94 /* Current number of expected connections */
95 unsigned int expecting; 95 unsigned int expecting;
96 96
97 /* Unique ID that identifies this conntrack*/
98 unsigned int id;
99
97 /* Helper. if any */ 100 /* Helper. if any */
98 struct nf_conntrack_helper *helper; 101 struct nf_conntrack_helper *helper;
99 102
@@ -140,6 +143,9 @@ struct nf_conntrack_expect
140 /* Usage count. */ 143 /* Usage count. */
141 atomic_t use; 144 atomic_t use;
142 145
146 /* Unique ID */
147 unsigned int id;
148
143 /* Flags */ 149 /* Flags */
144 unsigned int flags; 150 unsigned int flags;
145 151
@@ -190,6 +196,31 @@ static inline void nf_ct_put(struct nf_conn *ct)
190 nf_conntrack_put(&ct->ct_general); 196 nf_conntrack_put(&ct->ct_general);
191} 197}
192 198
199extern struct nf_conntrack_tuple_hash *
200__nf_conntrack_find(const struct nf_conntrack_tuple *tuple,
201 const struct nf_conn *ignored_conntrack);
202
203extern void nf_conntrack_hash_insert(struct nf_conn *ct);
204
205extern struct nf_conntrack_expect *
206__nf_conntrack_expect_find(const struct nf_conntrack_tuple *tuple);
207
208extern struct nf_conntrack_expect *
209nf_conntrack_expect_find(const struct nf_conntrack_tuple *tuple);
210
211extern void nf_ct_unlink_expect(struct nf_conntrack_expect *exp);
212
213extern void nf_ct_remove_expectations(struct nf_conn *ct);
214
215extern void nf_conntrack_flush(void);
216
217extern struct nf_conntrack_helper *
218nf_ct_helper_find_get( const struct nf_conntrack_tuple *tuple);
219extern void nf_ct_helper_put(struct nf_conntrack_helper *helper);
220
221extern struct nf_conntrack_helper *
222__nf_conntrack_helper_find_byname(const char *name);
223
193/* call to create an explicit dependency on nf_conntrack. */ 224/* call to create an explicit dependency on nf_conntrack. */
194extern void need_nf_conntrack(void); 225extern void need_nf_conntrack(void);
195 226
diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h
index 5a66b2a3a623..86ec8174ad02 100644
--- a/include/net/netfilter/nf_conntrack_helper.h
+++ b/include/net/netfilter/nf_conntrack_helper.h
@@ -33,6 +33,8 @@ struct nf_conntrack_helper
33 unsigned int protoff, 33 unsigned int protoff,
34 struct nf_conn *ct, 34 struct nf_conn *ct,
35 enum ip_conntrack_info conntrackinfo); 35 enum ip_conntrack_info conntrackinfo);
36
37 int (*to_nfattr)(struct sk_buff *skb, const struct nf_conn *ct);
36}; 38};
37 39
38extern int nf_conntrack_helper_register(struct nf_conntrack_helper *); 40extern int nf_conntrack_helper_register(struct nf_conntrack_helper *);
diff --git a/include/net/netfilter/nf_conntrack_l3proto.h b/include/net/netfilter/nf_conntrack_l3proto.h
index 01663e5b33df..67856eb93b43 100644
--- a/include/net/netfilter/nf_conntrack_l3proto.h
+++ b/include/net/netfilter/nf_conntrack_l3proto.h
@@ -14,6 +14,8 @@
14#include <linux/seq_file.h> 14#include <linux/seq_file.h>
15#include <net/netfilter/nf_conntrack.h> 15#include <net/netfilter/nf_conntrack.h>
16 16
17struct nfattr;
18
17struct nf_conntrack_l3proto 19struct nf_conntrack_l3proto
18{ 20{
19 /* Next pointer. */ 21 /* Next pointer. */
@@ -70,6 +72,12 @@ struct nf_conntrack_l3proto
70 72
71 u_int32_t (*get_features)(const struct nf_conntrack_tuple *tuple); 73 u_int32_t (*get_features)(const struct nf_conntrack_tuple *tuple);
72 74
75 int (*tuple_to_nfattr)(struct sk_buff *skb,
76 const struct nf_conntrack_tuple *t);
77
78 int (*nfattr_to_tuple)(struct nfattr *tb[],
79 struct nf_conntrack_tuple *t);
80
73 /* Module (if any) which this is connected to. */ 81 /* Module (if any) which this is connected to. */
74 struct module *me; 82 struct module *me;
75}; 83};
@@ -81,11 +89,16 @@ extern int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto);
81extern void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto); 89extern void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto);
82 90
83static inline struct nf_conntrack_l3proto * 91static inline struct nf_conntrack_l3proto *
84nf_ct_find_l3proto(u_int16_t l3proto) 92__nf_ct_l3proto_find(u_int16_t l3proto)
85{ 93{
86 return nf_ct_l3protos[l3proto]; 94 return nf_ct_l3protos[l3proto];
87} 95}
88 96
97extern struct nf_conntrack_l3proto *
98nf_ct_l3proto_find_get(u_int16_t l3proto);
99
100extern void nf_ct_l3proto_put(struct nf_conntrack_l3proto *p);
101
89/* Existing built-in protocols */ 102/* Existing built-in protocols */
90extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4; 103extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4;
91extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6; 104extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6;
diff --git a/include/net/netfilter/nf_conntrack_protocol.h b/include/net/netfilter/nf_conntrack_protocol.h
index b3afda35397a..1f33737fcea5 100644
--- a/include/net/netfilter/nf_conntrack_protocol.h
+++ b/include/net/netfilter/nf_conntrack_protocol.h
@@ -12,6 +12,7 @@
12#include <net/netfilter/nf_conntrack.h> 12#include <net/netfilter/nf_conntrack.h>
13 13
14struct seq_file; 14struct seq_file;
15struct nfattr;
15 16
16struct nf_conntrack_protocol 17struct nf_conntrack_protocol
17{ 18{
@@ -66,6 +67,18 @@ struct nf_conntrack_protocol
66 enum ip_conntrack_info *ctinfo, 67 enum ip_conntrack_info *ctinfo,
67 int pf, unsigned int hooknum); 68 int pf, unsigned int hooknum);
68 69
70 /* convert protoinfo to nfnetink attributes */
71 int (*to_nfattr)(struct sk_buff *skb, struct nfattr *nfa,
72 const struct nf_conn *ct);
73
74 /* convert nfnetlink attributes to protoinfo */
75 int (*from_nfattr)(struct nfattr *tb[], struct nf_conn *ct);
76
77 int (*tuple_to_nfattr)(struct sk_buff *skb,
78 const struct nf_conntrack_tuple *t);
79 int (*nfattr_to_tuple)(struct nfattr *tb[],
80 struct nf_conntrack_tuple *t);
81
69 /* Module (if any) which this is connected to. */ 82 /* Module (if any) which this is connected to. */
70 struct module *me; 83 struct module *me;
71}; 84};
@@ -80,12 +93,23 @@ extern struct nf_conntrack_protocol nf_conntrack_generic_protocol;
80extern struct nf_conntrack_protocol **nf_ct_protos[PF_MAX]; 93extern struct nf_conntrack_protocol **nf_ct_protos[PF_MAX];
81 94
82extern struct nf_conntrack_protocol * 95extern struct nf_conntrack_protocol *
83nf_ct_find_proto(u_int16_t l3proto, u_int8_t protocol); 96__nf_ct_proto_find(u_int16_t l3proto, u_int8_t protocol);
97
98extern struct nf_conntrack_protocol *
99nf_ct_proto_find_get(u_int16_t l3proto, u_int8_t protocol);
100
101extern void nf_ct_proto_put(struct nf_conntrack_protocol *p);
84 102
85/* Protocol registration. */ 103/* Protocol registration. */
86extern int nf_conntrack_protocol_register(struct nf_conntrack_protocol *proto); 104extern int nf_conntrack_protocol_register(struct nf_conntrack_protocol *proto);
87extern void nf_conntrack_protocol_unregister(struct nf_conntrack_protocol *proto); 105extern void nf_conntrack_protocol_unregister(struct nf_conntrack_protocol *proto);
88 106
107/* Generic netlink helpers */
108extern int nf_ct_port_tuple_to_nfattr(struct sk_buff *skb,
109 const struct nf_conntrack_tuple *tuple);
110extern int nf_ct_port_nfattr_to_tuple(struct nfattr *tb[],
111 struct nf_conntrack_tuple *t);
112
89/* Log invalid packets */ 113/* Log invalid packets */
90extern unsigned int nf_ct_log_invalid; 114extern unsigned int nf_ct_log_invalid;
91 115
diff --git a/include/pcmcia/cs.h b/include/pcmcia/cs.h
index 2cab39f49eb2..52660f32663d 100644
--- a/include/pcmcia/cs.h
+++ b/include/pcmcia/cs.h
@@ -382,7 +382,6 @@ enum service {
382struct pcmcia_socket; 382struct pcmcia_socket;
383 383
384int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, conf_reg_t *reg); 384int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, conf_reg_t *reg);
385int pcmcia_deregister_client(struct pcmcia_device *p_dev);
386int pcmcia_get_configuration_info(struct pcmcia_device *p_dev, config_info_t *config); 385int pcmcia_get_configuration_info(struct pcmcia_device *p_dev, config_info_t *config);
387int pcmcia_get_first_window(window_handle_t *win, win_req_t *req); 386int pcmcia_get_first_window(window_handle_t *win, win_req_t *req);
388int pcmcia_get_next_window(window_handle_t *win, win_req_t *req); 387int pcmcia_get_next_window(window_handle_t *win, win_req_t *req);
@@ -390,7 +389,6 @@ int pcmcia_get_status(struct pcmcia_device *p_dev, cs_status_t *status);
390int pcmcia_get_mem_page(window_handle_t win, memreq_t *req); 389int pcmcia_get_mem_page(window_handle_t win, memreq_t *req);
391int pcmcia_map_mem_page(window_handle_t win, memreq_t *req); 390int pcmcia_map_mem_page(window_handle_t win, memreq_t *req);
392int pcmcia_modify_configuration(struct pcmcia_device *p_dev, modconf_t *mod); 391int pcmcia_modify_configuration(struct pcmcia_device *p_dev, modconf_t *mod);
393int pcmcia_register_client(client_handle_t *handle, client_reg_t *req);
394int pcmcia_release_configuration(struct pcmcia_device *p_dev); 392int pcmcia_release_configuration(struct pcmcia_device *p_dev);
395int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req); 393int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req);
396int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req); 394int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req);
diff --git a/include/pcmcia/ds.h b/include/pcmcia/ds.h
index cb8b6e6ce66c..8e2a96396478 100644
--- a/include/pcmcia/ds.h
+++ b/include/pcmcia/ds.h
@@ -133,10 +133,12 @@ typedef struct dev_link_t {
133struct pcmcia_socket; 133struct pcmcia_socket;
134 134
135struct pcmcia_driver { 135struct pcmcia_driver {
136 dev_link_t *(*attach)(void); 136 int (*probe) (struct pcmcia_device *dev);
137 int (*event) (event_t event, int priority, 137 void (*remove) (struct pcmcia_device *dev);
138 event_callback_args_t *); 138
139 void (*detach)(dev_link_t *); 139 int (*suspend) (struct pcmcia_device *dev);
140 int (*resume) (struct pcmcia_device *dev);
141
140 struct module *owner; 142 struct module *owner;
141 struct pcmcia_device_id *id_table; 143 struct pcmcia_device_id *id_table;
142 struct device_driver drv; 144 struct device_driver drv;
@@ -164,7 +166,6 @@ struct pcmcia_device {
164 /* deprecated, a cleaned up version will be moved into this 166 /* deprecated, a cleaned up version will be moved into this
165 struct soon */ 167 struct soon */
166 dev_link_t *instance; 168 dev_link_t *instance;
167 event_callback_args_t event_callback_args;
168 u_int state; 169 u_int state;
169 170
170 /* information about this device */ 171 /* information about this device */
@@ -193,6 +194,8 @@ struct pcmcia_device {
193#define handle_to_pdev(handle) (handle) 194#define handle_to_pdev(handle) (handle)
194#define handle_to_dev(handle) (handle->dev) 195#define handle_to_dev(handle) (handle->dev)
195 196
197#define dev_to_instance(dev) (dev->instance)
198
196/* error reporting */ 199/* error reporting */
197void cs_error(client_handle_t handle, int func, int ret); 200void cs_error(client_handle_t handle, int func, int ret);
198 201
diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h
index e788bbc5657d..2889a69a7a8f 100644
--- a/include/pcmcia/ss.h
+++ b/include/pcmcia/ss.h
@@ -118,16 +118,14 @@ struct pcmcia_socket;
118struct pccard_operations { 118struct pccard_operations {
119 int (*init)(struct pcmcia_socket *sock); 119 int (*init)(struct pcmcia_socket *sock);
120 int (*suspend)(struct pcmcia_socket *sock); 120 int (*suspend)(struct pcmcia_socket *sock);
121 int (*register_callback)(struct pcmcia_socket *sock, void (*handler)(void *, unsigned int), void * info);
122 int (*get_status)(struct pcmcia_socket *sock, u_int *value); 121 int (*get_status)(struct pcmcia_socket *sock, u_int *value);
123 int (*get_socket)(struct pcmcia_socket *sock, socket_state_t *state);
124 int (*set_socket)(struct pcmcia_socket *sock, socket_state_t *state); 122 int (*set_socket)(struct pcmcia_socket *sock, socket_state_t *state);
125 int (*set_io_map)(struct pcmcia_socket *sock, struct pccard_io_map *io); 123 int (*set_io_map)(struct pcmcia_socket *sock, struct pccard_io_map *io);
126 int (*set_mem_map)(struct pcmcia_socket *sock, struct pccard_mem_map *mem); 124 int (*set_mem_map)(struct pcmcia_socket *sock, struct pccard_mem_map *mem);
127}; 125};
128 126
129struct pccard_resource_ops { 127struct pccard_resource_ops {
130 void (*validate_mem) (struct pcmcia_socket *s); 128 int (*validate_mem) (struct pcmcia_socket *s);
131 int (*adjust_io_region) (struct resource *res, 129 int (*adjust_io_region) (struct resource *res,
132 unsigned long r_start, 130 unsigned long r_start,
133 unsigned long r_end, 131 unsigned long r_end,
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 11321197338e..ba442883e877 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -20,6 +20,7 @@
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/rtnetlink.h> 22#include <linux/rtnetlink.h>
23#include <linux/if_ether.h>
23#include <net/sock.h> 24#include <net/sock.h>
24 25
25#include "br_private.h" 26#include "br_private.h"
@@ -323,7 +324,7 @@ int br_del_bridge(const char *name)
323 return ret; 324 return ret;
324} 325}
325 326
326/* Mtu of the bridge pseudo-device 1500 or the minimum of the ports */ 327/* MTU of the bridge pseudo-device: ETH_DATA_LEN or the minimum of the ports */
327int br_min_mtu(const struct net_bridge *br) 328int br_min_mtu(const struct net_bridge *br)
328{ 329{
329 const struct net_bridge_port *p; 330 const struct net_bridge_port *p;
@@ -332,7 +333,7 @@ int br_min_mtu(const struct net_bridge *br)
332 ASSERT_RTNL(); 333 ASSERT_RTNL();
333 334
334 if (list_empty(&br->port_list)) 335 if (list_empty(&br->port_list))
335 mtu = 1500; 336 mtu = ETH_DATA_LEN;
336 else { 337 else {
337 list_for_each_entry(p, &br->port_list, list) { 338 list_for_each_entry(p, &br->port_list, list) {
338 if (!mtu || p->dev->mtu < mtu) 339 if (!mtu || p->dev->mtu < mtu)
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index e24577367274..9f4dbeb59315 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -53,6 +53,7 @@
53#include <linux/errno.h> 53#include <linux/errno.h>
54#include <linux/config.h> 54#include <linux/config.h>
55#include <linux/init.h> 55#include <linux/init.h>
56#include <linux/if_ether.h>
56#include <net/dst.h> 57#include <net/dst.h>
57#include <net/arp.h> 58#include <net/arp.h>
58#include <net/sock.h> 59#include <net/sock.h>
@@ -251,7 +252,7 @@ static int eth_mac_addr(struct net_device *dev, void *p)
251 252
252static int eth_change_mtu(struct net_device *dev, int new_mtu) 253static int eth_change_mtu(struct net_device *dev, int new_mtu)
253{ 254{
254 if ((new_mtu < 68) || (new_mtu > 1500)) 255 if (new_mtu < 68 || new_mtu > ETH_DATA_LEN)
255 return -EINVAL; 256 return -EINVAL;
256 dev->mtu = new_mtu; 257 dev->mtu = new_mtu;
257 return 0; 258 return 0;
@@ -272,7 +273,7 @@ void ether_setup(struct net_device *dev)
272 273
273 dev->type = ARPHRD_ETHER; 274 dev->type = ARPHRD_ETHER;
274 dev->hard_header_len = ETH_HLEN; 275 dev->hard_header_len = ETH_HLEN;
275 dev->mtu = 1500; /* eth_mtu */ 276 dev->mtu = ETH_DATA_LEN;
276 dev->addr_len = ETH_ALEN; 277 dev->addr_len = ETH_ALEN;
277 dev->tx_queue_len = 1000; /* Ethernet wants good queues */ 278 dev->tx_queue_len = 1000; /* Ethernet wants good queues */
278 dev->flags = IFF_BROADCAST|IFF_MULTICAST; 279 dev->flags = IFF_BROADCAST|IFF_MULTICAST;
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 46f9d9cf7a5f..912c42f57c79 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -28,6 +28,7 @@
28#include <linux/inetdevice.h> 28#include <linux/inetdevice.h>
29#include <linux/igmp.h> 29#include <linux/igmp.h>
30#include <linux/netfilter_ipv4.h> 30#include <linux/netfilter_ipv4.h>
31#include <linux/if_ether.h>
31 32
32#include <net/sock.h> 33#include <net/sock.h>
33#include <net/ip.h> 34#include <net/ip.h>
@@ -1140,7 +1141,7 @@ static void ipgre_tunnel_setup(struct net_device *dev)
1140 1141
1141 dev->type = ARPHRD_IPGRE; 1142 dev->type = ARPHRD_IPGRE;
1142 dev->hard_header_len = LL_MAX_HEADER + sizeof(struct iphdr) + 4; 1143 dev->hard_header_len = LL_MAX_HEADER + sizeof(struct iphdr) + 4;
1143 dev->mtu = 1500 - sizeof(struct iphdr) - 4; 1144 dev->mtu = ETH_DATA_LEN - sizeof(struct iphdr) - 4;
1144 dev->flags = IFF_NOARP; 1145 dev->flags = IFF_NOARP;
1145 dev->iflink = 0; 1146 dev->iflink = 0;
1146 dev->addr_len = 4; 1147 dev->addr_len = 4;
@@ -1152,7 +1153,7 @@ static int ipgre_tunnel_init(struct net_device *dev)
1152 struct ip_tunnel *tunnel; 1153 struct ip_tunnel *tunnel;
1153 struct iphdr *iph; 1154 struct iphdr *iph;
1154 int hlen = LL_MAX_HEADER; 1155 int hlen = LL_MAX_HEADER;
1155 int mtu = 1500; 1156 int mtu = ETH_DATA_LEN;
1156 int addend = sizeof(struct iphdr) + 4; 1157 int addend = sizeof(struct iphdr) + 4;
1157 1158
1158 tunnel = (struct ip_tunnel*)dev->priv; 1159 tunnel = (struct ip_tunnel*)dev->priv;
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 2a830de3a699..71da31818cfc 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -202,13 +202,11 @@ static inline int ip_finish_output2(struct sk_buff *skb)
202 202
203static inline int ip_finish_output(struct sk_buff *skb) 203static inline int ip_finish_output(struct sk_buff *skb)
204{ 204{
205 struct net_device *dev = skb->dst->dev; 205 if (skb->len > dst_mtu(skb->dst) &&
206 206 !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size))
207 skb->dev = dev; 207 return ip_fragment(skb, ip_finish_output2);
208 skb->protocol = htons(ETH_P_IP); 208 else
209 209 return ip_finish_output2(skb);
210 return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev,
211 ip_finish_output2);
212} 210}
213 211
214int ip_mc_output(struct sk_buff *skb) 212int ip_mc_output(struct sk_buff *skb)
@@ -265,21 +263,21 @@ int ip_mc_output(struct sk_buff *skb)
265 newskb->dev, ip_dev_loopback_xmit); 263 newskb->dev, ip_dev_loopback_xmit);
266 } 264 }
267 265
268 if (skb->len > dst_mtu(&rt->u.dst)) 266 return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dev,
269 return ip_fragment(skb, ip_finish_output); 267 ip_finish_output);
270 else
271 return ip_finish_output(skb);
272} 268}
273 269
274int ip_output(struct sk_buff *skb) 270int ip_output(struct sk_buff *skb)
275{ 271{
272 struct net_device *dev = skb->dst->dev;
273
276 IP_INC_STATS(IPSTATS_MIB_OUTREQUESTS); 274 IP_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
277 275
278 if (skb->len > dst_mtu(skb->dst) && 276 skb->dev = dev;
279 !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size)) 277 skb->protocol = htons(ETH_P_IP);
280 return ip_fragment(skb, ip_finish_output); 278
281 else 279 return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev,
282 return ip_finish_output(skb); 280 ip_finish_output);
283} 281}
284 282
285int ip_queue_xmit(struct sk_buff *skb, int ipfragok) 283int ip_queue_xmit(struct sk_buff *skb, int ipfragok)
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index c05c1df0bb04..35571cff81c6 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -108,6 +108,7 @@
108#include <linux/mroute.h> 108#include <linux/mroute.h>
109#include <linux/init.h> 109#include <linux/init.h>
110#include <linux/netfilter_ipv4.h> 110#include <linux/netfilter_ipv4.h>
111#include <linux/if_ether.h>
111 112
112#include <net/sock.h> 113#include <net/sock.h>
113#include <net/ip.h> 114#include <net/ip.h>
@@ -786,7 +787,7 @@ static void ipip_tunnel_setup(struct net_device *dev)
786 787
787 dev->type = ARPHRD_TUNNEL; 788 dev->type = ARPHRD_TUNNEL;
788 dev->hard_header_len = LL_MAX_HEADER + sizeof(struct iphdr); 789 dev->hard_header_len = LL_MAX_HEADER + sizeof(struct iphdr);
789 dev->mtu = 1500 - sizeof(struct iphdr); 790 dev->mtu = ETH_DATA_LEN - sizeof(struct iphdr);
790 dev->flags = IFF_NOARP; 791 dev->flags = IFF_NOARP;
791 dev->iflink = 0; 792 dev->iflink = 0;
792 dev->addr_len = 4; 793 dev->addr_len = 4;
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index caa3b7d2e48a..9a5c0ce7ff35 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -49,6 +49,7 @@
49#include <linux/seq_file.h> 49#include <linux/seq_file.h>
50#include <linux/mroute.h> 50#include <linux/mroute.h>
51#include <linux/init.h> 51#include <linux/init.h>
52#include <linux/if_ether.h>
52#include <net/ip.h> 53#include <net/ip.h>
53#include <net/protocol.h> 54#include <net/protocol.h>
54#include <linux/skbuff.h> 55#include <linux/skbuff.h>
@@ -193,7 +194,7 @@ static struct net_device_stats *reg_vif_get_stats(struct net_device *dev)
193static void reg_vif_setup(struct net_device *dev) 194static void reg_vif_setup(struct net_device *dev)
194{ 195{
195 dev->type = ARPHRD_PIMREG; 196 dev->type = ARPHRD_PIMREG;
196 dev->mtu = 1500 - sizeof(struct iphdr) - 8; 197 dev->mtu = ETH_DATA_LEN - sizeof(struct iphdr) - 8;
197 dev->flags = IFF_NOARP; 198 dev->flags = IFF_NOARP;
198 dev->hard_start_xmit = reg_vif_xmit; 199 dev->hard_start_xmit = reg_vif_xmit;
199 dev->get_stats = reg_vif_get_stats; 200 dev->get_stats = reg_vif_get_stats;
diff --git a/net/ipv4/ipvs/ip_vs_conn.c b/net/ipv4/ipvs/ip_vs_conn.c
index 81d90354c928..87b83813cf2c 100644
--- a/net/ipv4/ipvs/ip_vs_conn.c
+++ b/net/ipv4/ipvs/ip_vs_conn.c
@@ -24,6 +24,7 @@
24 * 24 *
25 */ 25 */
26 26
27#include <linux/interrupt.h>
27#include <linux/in.h> 28#include <linux/in.h>
28#include <linux/net.h> 29#include <linux/net.h>
29#include <linux/kernel.h> 30#include <linux/kernel.h>
diff --git a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c
index 1aca94a9fd8b..3f47ad8e1cad 100644
--- a/net/ipv4/ipvs/ip_vs_core.c
+++ b/net/ipv4/ipvs/ip_vs_core.c
@@ -532,11 +532,8 @@ static unsigned int ip_vs_post_routing(unsigned int hooknum,
532{ 532{
533 if (!((*pskb)->ipvs_property)) 533 if (!((*pskb)->ipvs_property))
534 return NF_ACCEPT; 534 return NF_ACCEPT;
535
536 /* The packet was sent from IPVS, exit this chain */ 535 /* The packet was sent from IPVS, exit this chain */
537 (*okfn)(*pskb); 536 return NF_STOP;
538
539 return NF_STOLEN;
540} 537}
541 538
542u16 ip_vs_checksum_complete(struct sk_buff *skb, int offset) 539u16 ip_vs_checksum_complete(struct sk_buff *skb, int offset)
diff --git a/net/ipv4/ipvs/ip_vs_est.c b/net/ipv4/ipvs/ip_vs_est.c
index e7004741ac73..c453e1e57f4b 100644
--- a/net/ipv4/ipvs/ip_vs_est.c
+++ b/net/ipv4/ipvs/ip_vs_est.c
@@ -18,6 +18,7 @@
18#include <linux/jiffies.h> 18#include <linux/jiffies.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/types.h> 20#include <linux/types.h>
21#include <linux/interrupt.h>
21 22
22#include <net/ip_vs.h> 23#include <net/ip_vs.h>
23 24
diff --git a/net/ipv4/ipvs/ip_vs_sched.c b/net/ipv4/ipvs/ip_vs_sched.c
index 0f7c56a225bd..8bc42b76223d 100644
--- a/net/ipv4/ipvs/ip_vs_sched.c
+++ b/net/ipv4/ipvs/ip_vs_sched.c
@@ -22,6 +22,7 @@
22#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/sched.h> 23#include <linux/sched.h>
24#include <linux/spinlock.h> 24#include <linux/spinlock.h>
25#include <linux/interrupt.h>
25#include <asm/string.h> 26#include <asm/string.h>
26#include <linux/kmod.h> 27#include <linux/kmod.h>
27 28
diff --git a/net/ipv4/netfilter/ip_conntrack_amanda.c b/net/ipv4/netfilter/ip_conntrack_amanda.c
index 0366eedb4d70..84e4f79b7ffa 100644
--- a/net/ipv4/netfilter/ip_conntrack_amanda.c
+++ b/net/ipv4/netfilter/ip_conntrack_amanda.c
@@ -36,7 +36,7 @@ static unsigned int master_timeout = 300;
36MODULE_AUTHOR("Brian J. Murrell <netfilter@interlinx.bc.ca>"); 36MODULE_AUTHOR("Brian J. Murrell <netfilter@interlinx.bc.ca>");
37MODULE_DESCRIPTION("Amanda connection tracking module"); 37MODULE_DESCRIPTION("Amanda connection tracking module");
38MODULE_LICENSE("GPL"); 38MODULE_LICENSE("GPL");
39module_param(master_timeout, int, 0600); 39module_param(master_timeout, uint, 0600);
40MODULE_PARM_DESC(master_timeout, "timeout for the master connection"); 40MODULE_PARM_DESC(master_timeout, "timeout for the master connection");
41 41
42static const char *conns[] = { "DATA ", "MESG ", "INDEX " }; 42static const char *conns[] = { "DATA ", "MESG ", "INDEX " };
diff --git a/net/ipv4/netfilter/ip_conntrack_ftp.c b/net/ipv4/netfilter/ip_conntrack_ftp.c
index 68b173bcda60..e627e5856172 100644
--- a/net/ipv4/netfilter/ip_conntrack_ftp.c
+++ b/net/ipv4/netfilter/ip_conntrack_ftp.c
@@ -34,7 +34,7 @@ static int ports_c;
34module_param_array(ports, ushort, &ports_c, 0400); 34module_param_array(ports, ushort, &ports_c, 0400);
35 35
36static int loose; 36static int loose;
37module_param(loose, int, 0600); 37module_param(loose, bool, 0600);
38 38
39unsigned int (*ip_nat_ftp_hook)(struct sk_buff **pskb, 39unsigned int (*ip_nat_ftp_hook)(struct sk_buff **pskb,
40 enum ip_conntrack_info ctinfo, 40 enum ip_conntrack_info ctinfo,
diff --git a/net/ipv4/netfilter/ip_conntrack_irc.c b/net/ipv4/netfilter/ip_conntrack_irc.c
index d7c40421d0d1..c51a2cf71b4b 100644
--- a/net/ipv4/netfilter/ip_conntrack_irc.c
+++ b/net/ipv4/netfilter/ip_conntrack_irc.c
@@ -36,7 +36,7 @@
36#define MAX_PORTS 8 36#define MAX_PORTS 8
37static unsigned short ports[MAX_PORTS]; 37static unsigned short ports[MAX_PORTS];
38static int ports_c; 38static int ports_c;
39static int max_dcc_channels = 8; 39static unsigned int max_dcc_channels = 8;
40static unsigned int dcc_timeout = 300; 40static unsigned int dcc_timeout = 300;
41/* This is slow, but it's simple. --RR */ 41/* This is slow, but it's simple. --RR */
42static char *irc_buffer; 42static char *irc_buffer;
@@ -54,9 +54,9 @@ MODULE_DESCRIPTION("IRC (DCC) connection tracking helper");
54MODULE_LICENSE("GPL"); 54MODULE_LICENSE("GPL");
55module_param_array(ports, ushort, &ports_c, 0400); 55module_param_array(ports, ushort, &ports_c, 0400);
56MODULE_PARM_DESC(ports, "port numbers of IRC servers"); 56MODULE_PARM_DESC(ports, "port numbers of IRC servers");
57module_param(max_dcc_channels, int, 0400); 57module_param(max_dcc_channels, uint, 0400);
58MODULE_PARM_DESC(max_dcc_channels, "max number of expected DCC channels per IRC session"); 58MODULE_PARM_DESC(max_dcc_channels, "max number of expected DCC channels per IRC session");
59module_param(dcc_timeout, int, 0400); 59module_param(dcc_timeout, uint, 0400);
60MODULE_PARM_DESC(dcc_timeout, "timeout on for unestablished DCC channels"); 60MODULE_PARM_DESC(dcc_timeout, "timeout on for unestablished DCC channels");
61 61
62static const char *dccprotos[] = { "SEND ", "CHAT ", "MOVE ", "TSEND ", "SCHAT " }; 62static const char *dccprotos[] = { "SEND ", "CHAT ", "MOVE ", "TSEND ", "SCHAT " };
@@ -254,10 +254,6 @@ static int __init init(void)
254 printk("ip_conntrack_irc: max_dcc_channels must be a positive integer\n"); 254 printk("ip_conntrack_irc: max_dcc_channels must be a positive integer\n");
255 return -EBUSY; 255 return -EBUSY;
256 } 256 }
257 if (dcc_timeout < 0) {
258 printk("ip_conntrack_irc: dcc_timeout must be a positive integer\n");
259 return -EBUSY;
260 }
261 257
262 irc_buffer = kmalloc(65536, GFP_KERNEL); 258 irc_buffer = kmalloc(65536, GFP_KERNEL);
263 if (!irc_buffer) 259 if (!irc_buffer)
diff --git a/net/ipv4/netfilter/ip_conntrack_netbios_ns.c b/net/ipv4/netfilter/ip_conntrack_netbios_ns.c
index 186646eb249f..4e68e16a2612 100644
--- a/net/ipv4/netfilter/ip_conntrack_netbios_ns.c
+++ b/net/ipv4/netfilter/ip_conntrack_netbios_ns.c
@@ -37,7 +37,7 @@ MODULE_DESCRIPTION("NetBIOS name service broadcast connection tracking helper");
37MODULE_LICENSE("GPL"); 37MODULE_LICENSE("GPL");
38 38
39static unsigned int timeout = 3; 39static unsigned int timeout = 3;
40module_param(timeout, int, 0600); 40module_param(timeout, uint, 0400);
41MODULE_PARM_DESC(timeout, "timeout for master connection/replies in seconds"); 41MODULE_PARM_DESC(timeout, "timeout for master connection/replies in seconds");
42 42
43static int help(struct sk_buff **pskb, 43static int help(struct sk_buff **pskb,
diff --git a/net/ipv4/netfilter/ip_conntrack_netlink.c b/net/ipv4/netfilter/ip_conntrack_netlink.c
index 91fe8f2e38ff..c9ebbe0d2d9c 100644
--- a/net/ipv4/netfilter/ip_conntrack_netlink.c
+++ b/net/ipv4/netfilter/ip_conntrack_netlink.c
@@ -79,6 +79,7 @@ ctnetlink_dump_tuples(struct sk_buff *skb,
79 const struct ip_conntrack_tuple *tuple) 79 const struct ip_conntrack_tuple *tuple)
80{ 80{
81 struct nfattr *nest_parms; 81 struct nfattr *nest_parms;
82 int ret;
82 83
83 nest_parms = NFA_NEST(skb, CTA_TUPLE_IP); 84 nest_parms = NFA_NEST(skb, CTA_TUPLE_IP);
84 NFA_PUT(skb, CTA_IP_V4_SRC, sizeof(u_int32_t), &tuple->src.ip); 85 NFA_PUT(skb, CTA_IP_V4_SRC, sizeof(u_int32_t), &tuple->src.ip);
@@ -86,10 +87,10 @@ ctnetlink_dump_tuples(struct sk_buff *skb,
86 NFA_NEST_END(skb, nest_parms); 87 NFA_NEST_END(skb, nest_parms);
87 88
88 nest_parms = NFA_NEST(skb, CTA_TUPLE_PROTO); 89 nest_parms = NFA_NEST(skb, CTA_TUPLE_PROTO);
89 ctnetlink_dump_tuples_proto(skb, tuple); 90 ret = ctnetlink_dump_tuples_proto(skb, tuple);
90 NFA_NEST_END(skb, nest_parms); 91 NFA_NEST_END(skb, nest_parms);
91 92
92 return 0; 93 return ret;
93 94
94nfattr_failure: 95nfattr_failure:
95 return -1; 96 return -1;
@@ -160,7 +161,7 @@ ctnetlink_dump_helpinfo(struct sk_buff *skb, const struct ip_conntrack *ct)
160 return 0; 161 return 0;
161 162
162 nest_helper = NFA_NEST(skb, CTA_HELP); 163 nest_helper = NFA_NEST(skb, CTA_HELP);
163 NFA_PUT(skb, CTA_HELP_NAME, CTA_HELP_MAXNAMESIZE, &ct->helper->name); 164 NFA_PUT(skb, CTA_HELP_NAME, strlen(ct->helper->name), ct->helper->name);
164 165
165 if (ct->helper->to_nfattr) 166 if (ct->helper->to_nfattr)
166 ct->helper->to_nfattr(skb, ct); 167 ct->helper->to_nfattr(skb, ct);
@@ -229,7 +230,7 @@ nfattr_failure:
229static inline int 230static inline int
230ctnetlink_dump_use(struct sk_buff *skb, const struct ip_conntrack *ct) 231ctnetlink_dump_use(struct sk_buff *skb, const struct ip_conntrack *ct)
231{ 232{
232 unsigned int use = htonl(atomic_read(&ct->ct_general.use)); 233 u_int32_t use = htonl(atomic_read(&ct->ct_general.use));
233 234
234 NFA_PUT(skb, CTA_USE, sizeof(u_int32_t), &use); 235 NFA_PUT(skb, CTA_USE, sizeof(u_int32_t), &use);
235 return 0; 236 return 0;
@@ -311,29 +312,22 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
311 if (events & IPCT_DESTROY) { 312 if (events & IPCT_DESTROY) {
312 type = IPCTNL_MSG_CT_DELETE; 313 type = IPCTNL_MSG_CT_DELETE;
313 group = NFNLGRP_CONNTRACK_DESTROY; 314 group = NFNLGRP_CONNTRACK_DESTROY;
314 goto alloc_skb; 315 } else if (events & (IPCT_NEW | IPCT_RELATED)) {
315 }
316 if (events & (IPCT_NEW | IPCT_RELATED)) {
317 type = IPCTNL_MSG_CT_NEW; 316 type = IPCTNL_MSG_CT_NEW;
318 flags = NLM_F_CREATE|NLM_F_EXCL; 317 flags = NLM_F_CREATE|NLM_F_EXCL;
319 /* dump everything */ 318 /* dump everything */
320 events = ~0UL; 319 events = ~0UL;
321 group = NFNLGRP_CONNTRACK_NEW; 320 group = NFNLGRP_CONNTRACK_NEW;
322 goto alloc_skb; 321 } else if (events & (IPCT_STATUS |
323 }
324 if (events & (IPCT_STATUS |
325 IPCT_PROTOINFO | 322 IPCT_PROTOINFO |
326 IPCT_HELPER | 323 IPCT_HELPER |
327 IPCT_HELPINFO | 324 IPCT_HELPINFO |
328 IPCT_NATINFO)) { 325 IPCT_NATINFO)) {
329 type = IPCTNL_MSG_CT_NEW; 326 type = IPCTNL_MSG_CT_NEW;
330 group = NFNLGRP_CONNTRACK_UPDATE; 327 group = NFNLGRP_CONNTRACK_UPDATE;
331 goto alloc_skb; 328 } else
332 } 329 return NOTIFY_DONE;
333 330
334 return NOTIFY_DONE;
335
336alloc_skb:
337 /* FIXME: Check if there are any listeners before, don't hurt performance */ 331 /* FIXME: Check if there are any listeners before, don't hurt performance */
338 332
339 skb = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC); 333 skb = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC);
@@ -1037,6 +1031,11 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
1037 return err; 1031 return err;
1038 } 1032 }
1039 1033
1034#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
1035 if (cda[CTA_MARK-1])
1036 ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1]));
1037#endif
1038
1040 ct->helper = ip_conntrack_helper_find_get(rtuple); 1039 ct->helper = ip_conntrack_helper_find_get(rtuple);
1041 1040
1042 add_timer(&ct->timeout); 1041 add_timer(&ct->timeout);
@@ -1045,11 +1044,6 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
1045 if (ct->helper) 1044 if (ct->helper)
1046 ip_conntrack_helper_put(ct->helper); 1045 ip_conntrack_helper_put(ct->helper);
1047 1046
1048#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
1049 if (cda[CTA_MARK-1])
1050 ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1]));
1051#endif
1052
1053 DEBUGP("conntrack with id %u inserted\n", ct->id); 1047 DEBUGP("conntrack with id %u inserted\n", ct->id);
1054 return 0; 1048 return 0;
1055 1049
@@ -1209,7 +1203,6 @@ static int ctnetlink_expect_event(struct notifier_block *this,
1209 unsigned int type; 1203 unsigned int type;
1210 unsigned char *b; 1204 unsigned char *b;
1211 int flags = 0; 1205 int flags = 0;
1212 u16 proto;
1213 1206
1214 if (events & IPEXP_NEW) { 1207 if (events & IPEXP_NEW) {
1215 type = IPCTNL_MSG_EXP_NEW; 1208 type = IPCTNL_MSG_EXP_NEW;
@@ -1236,7 +1229,6 @@ static int ctnetlink_expect_event(struct notifier_block *this,
1236 goto nfattr_failure; 1229 goto nfattr_failure;
1237 1230
1238 nlh->nlmsg_len = skb->tail - b; 1231 nlh->nlmsg_len = skb->tail - b;
1239 proto = exp->tuple.dst.protonum;
1240 nfnetlink_send(skb, 0, NFNLGRP_CONNTRACK_EXP_NEW, 0); 1232 nfnetlink_send(skb, 0, NFNLGRP_CONNTRACK_EXP_NEW, 0);
1241 return NOTIFY_DONE; 1233 return NOTIFY_DONE;
1242 1234
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
index 5f9925db608e..30fc21d6165a 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
@@ -47,20 +47,21 @@ static int icmp_pkt_to_tuple(const struct sk_buff *skb,
47 return 1; 47 return 1;
48} 48}
49 49
50/* Add 1; spaces filled with 0. */
51static const u_int8_t invmap[] = {
52 [ICMP_ECHO] = ICMP_ECHOREPLY + 1,
53 [ICMP_ECHOREPLY] = ICMP_ECHO + 1,
54 [ICMP_TIMESTAMP] = ICMP_TIMESTAMPREPLY + 1,
55 [ICMP_TIMESTAMPREPLY] = ICMP_TIMESTAMP + 1,
56 [ICMP_INFO_REQUEST] = ICMP_INFO_REPLY + 1,
57 [ICMP_INFO_REPLY] = ICMP_INFO_REQUEST + 1,
58 [ICMP_ADDRESS] = ICMP_ADDRESSREPLY + 1,
59 [ICMP_ADDRESSREPLY] = ICMP_ADDRESS + 1
60};
61
50static int icmp_invert_tuple(struct ip_conntrack_tuple *tuple, 62static int icmp_invert_tuple(struct ip_conntrack_tuple *tuple,
51 const struct ip_conntrack_tuple *orig) 63 const struct ip_conntrack_tuple *orig)
52{ 64{
53 /* Add 1; spaces filled with 0. */
54 static const u_int8_t invmap[]
55 = { [ICMP_ECHO] = ICMP_ECHOREPLY + 1,
56 [ICMP_ECHOREPLY] = ICMP_ECHO + 1,
57 [ICMP_TIMESTAMP] = ICMP_TIMESTAMPREPLY + 1,
58 [ICMP_TIMESTAMPREPLY] = ICMP_TIMESTAMP + 1,
59 [ICMP_INFO_REQUEST] = ICMP_INFO_REPLY + 1,
60 [ICMP_INFO_REPLY] = ICMP_INFO_REQUEST + 1,
61 [ICMP_ADDRESS] = ICMP_ADDRESSREPLY + 1,
62 [ICMP_ADDRESSREPLY] = ICMP_ADDRESS + 1};
63
64 if (orig->dst.u.icmp.type >= sizeof(invmap) 65 if (orig->dst.u.icmp.type >= sizeof(invmap)
65 || !invmap[orig->dst.u.icmp.type]) 66 || !invmap[orig->dst.u.icmp.type])
66 return 0; 67 return 0;
@@ -110,17 +111,17 @@ static int icmp_packet(struct ip_conntrack *ct,
110 return NF_ACCEPT; 111 return NF_ACCEPT;
111} 112}
112 113
113static const u_int8_t valid_new[] = {
114 [ICMP_ECHO] = 1,
115 [ICMP_TIMESTAMP] = 1,
116 [ICMP_INFO_REQUEST] = 1,
117 [ICMP_ADDRESS] = 1
118};
119
120/* Called when a new connection for this protocol found. */ 114/* Called when a new connection for this protocol found. */
121static int icmp_new(struct ip_conntrack *conntrack, 115static int icmp_new(struct ip_conntrack *conntrack,
122 const struct sk_buff *skb) 116 const struct sk_buff *skb)
123{ 117{
118 static const u_int8_t valid_new[] = {
119 [ICMP_ECHO] = 1,
120 [ICMP_TIMESTAMP] = 1,
121 [ICMP_INFO_REQUEST] = 1,
122 [ICMP_ADDRESS] = 1
123 };
124
124 if (conntrack->tuplehash[0].tuple.dst.u.icmp.type >= sizeof(valid_new) 125 if (conntrack->tuplehash[0].tuple.dst.u.icmp.type >= sizeof(valid_new)
125 || !valid_new[conntrack->tuplehash[0].tuple.dst.u.icmp.type]) { 126 || !valid_new[conntrack->tuplehash[0].tuple.dst.u.icmp.type]) {
126 /* Can't create a new ICMP `conn' with this. */ 127 /* Can't create a new ICMP `conn' with this. */
@@ -279,10 +280,6 @@ static int icmp_tuple_to_nfattr(struct sk_buff *skb,
279 NFA_PUT(skb, CTA_PROTO_ICMP_CODE, sizeof(u_int8_t), 280 NFA_PUT(skb, CTA_PROTO_ICMP_CODE, sizeof(u_int8_t),
280 &t->dst.u.icmp.code); 281 &t->dst.u.icmp.code);
281 282
282 if (t->dst.u.icmp.type >= sizeof(valid_new)
283 || !valid_new[t->dst.u.icmp.type])
284 return -EINVAL;
285
286 return 0; 283 return 0;
287 284
288nfattr_failure: 285nfattr_failure:
@@ -295,7 +292,7 @@ static int icmp_nfattr_to_tuple(struct nfattr *tb[],
295 if (!tb[CTA_PROTO_ICMP_TYPE-1] 292 if (!tb[CTA_PROTO_ICMP_TYPE-1]
296 || !tb[CTA_PROTO_ICMP_CODE-1] 293 || !tb[CTA_PROTO_ICMP_CODE-1]
297 || !tb[CTA_PROTO_ICMP_ID-1]) 294 || !tb[CTA_PROTO_ICMP_ID-1])
298 return -1; 295 return -EINVAL;
299 296
300 tuple->dst.u.icmp.type = 297 tuple->dst.u.icmp.type =
301 *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_TYPE-1]); 298 *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_TYPE-1]);
@@ -304,6 +301,10 @@ static int icmp_nfattr_to_tuple(struct nfattr *tb[],
304 tuple->src.u.icmp.id = 301 tuple->src.u.icmp.id =
305 *(u_int16_t *)NFA_DATA(tb[CTA_PROTO_ICMP_ID-1]); 302 *(u_int16_t *)NFA_DATA(tb[CTA_PROTO_ICMP_ID-1]);
306 303
304 if (tuple->dst.u.icmp.type >= sizeof(invmap)
305 || !invmap[tuple->dst.u.icmp.type])
306 return -EINVAL;
307
307 return 0; 308 return 0;
308} 309}
309#endif 310#endif
diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c
index a88bcc551244..7ba97783e741 100644
--- a/net/ipv4/netfilter/ip_conntrack_standalone.c
+++ b/net/ipv4/netfilter/ip_conntrack_standalone.c
@@ -451,30 +451,6 @@ static unsigned int ip_conntrack_defrag(unsigned int hooknum,
451 return NF_ACCEPT; 451 return NF_ACCEPT;
452} 452}
453 453
454static unsigned int ip_refrag(unsigned int hooknum,
455 struct sk_buff **pskb,
456 const struct net_device *in,
457 const struct net_device *out,
458 int (*okfn)(struct sk_buff *))
459{
460 struct rtable *rt = (struct rtable *)(*pskb)->dst;
461
462 /* We've seen it coming out the other side: confirm */
463 if (ip_confirm(hooknum, pskb, in, out, okfn) != NF_ACCEPT)
464 return NF_DROP;
465
466 /* Local packets are never produced too large for their
467 interface. We degfragment them at LOCAL_OUT, however,
468 so we have to refragment them here. */
469 if ((*pskb)->len > dst_mtu(&rt->u.dst) &&
470 !skb_shinfo(*pskb)->tso_size) {
471 /* No hook can be after us, so this should be OK. */
472 ip_fragment(*pskb, okfn);
473 return NF_STOLEN;
474 }
475 return NF_ACCEPT;
476}
477
478static unsigned int ip_conntrack_local(unsigned int hooknum, 454static unsigned int ip_conntrack_local(unsigned int hooknum,
479 struct sk_buff **pskb, 455 struct sk_buff **pskb,
480 const struct net_device *in, 456 const struct net_device *in,
@@ -544,7 +520,7 @@ static struct nf_hook_ops ip_conntrack_helper_in_ops = {
544 520
545/* Refragmenter; last chance. */ 521/* Refragmenter; last chance. */
546static struct nf_hook_ops ip_conntrack_out_ops = { 522static struct nf_hook_ops ip_conntrack_out_ops = {
547 .hook = ip_refrag, 523 .hook = ip_confirm,
548 .owner = THIS_MODULE, 524 .owner = THIS_MODULE,
549 .pf = PF_INET, 525 .pf = PF_INET,
550 .hooknum = NF_IP_POST_ROUTING, 526 .hooknum = NF_IP_POST_ROUTING,
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
index 30cd4e18c129..f04111f74e09 100644
--- a/net/ipv4/netfilter/ip_nat_standalone.c
+++ b/net/ipv4/netfilter/ip_nat_standalone.c
@@ -190,23 +190,6 @@ ip_nat_out(unsigned int hooknum,
190 || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) 190 || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr))
191 return NF_ACCEPT; 191 return NF_ACCEPT;
192 192
193 /* We can hit fragment here; forwarded packets get
194 defragmented by connection tracking coming in, then
195 fragmented (grr) by the forward code.
196
197 In future: If we have nfct != NULL, AND we have NAT
198 initialized, AND there is no helper, then we can do full
199 NAPT on the head, and IP-address-only NAT on the rest.
200
201 I'm starting to have nightmares about fragments. */
202
203 if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
204 *pskb = ip_ct_gather_frags(*pskb, IP_DEFRAG_NAT_OUT);
205
206 if (!*pskb)
207 return NF_STOLEN;
208 }
209
210 return ip_nat_fn(hooknum, pskb, in, out, okfn); 193 return ip_nat_fn(hooknum, pskb, in, out, okfn);
211} 194}
212 195
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
index f057025a719e..6693526ae128 100644
--- a/net/ipv4/netfilter/ipt_REJECT.c
+++ b/net/ipv4/netfilter/ipt_REJECT.c
@@ -203,7 +203,7 @@ static void send_reset(struct sk_buff *oldskb, int hook)
203 sizeof(struct tcphdr), 0)); 203 sizeof(struct tcphdr), 0));
204 204
205 /* Adjust IP TTL, DF */ 205 /* Adjust IP TTL, DF */
206 nskb->nh.iph->ttl = MAXTTL; 206 nskb->nh.iph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT);
207 /* Set DF, id = 0 */ 207 /* Set DF, id = 0 */
208 nskb->nh.iph->frag_off = htons(IP_DF); 208 nskb->nh.iph->frag_off = htons(IP_DF);
209 nskb->nh.iph->id = 0; 209 nskb->nh.iph->id = 0;
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c
index 2883ccd8a91d..38641cd06123 100644
--- a/net/ipv4/netfilter/ipt_ULOG.c
+++ b/net/ipv4/netfilter/ipt_ULOG.c
@@ -77,15 +77,15 @@ MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_NFLOG);
77#define PRINTR(format, args...) do { if (net_ratelimit()) printk(format , ## args); } while (0) 77#define PRINTR(format, args...) do { if (net_ratelimit()) printk(format , ## args); } while (0)
78 78
79static unsigned int nlbufsiz = 4096; 79static unsigned int nlbufsiz = 4096;
80module_param(nlbufsiz, uint, 0600); /* FIXME: Check size < 128k --RR */ 80module_param(nlbufsiz, uint, 0400);
81MODULE_PARM_DESC(nlbufsiz, "netlink buffer size"); 81MODULE_PARM_DESC(nlbufsiz, "netlink buffer size");
82 82
83static unsigned int flushtimeout = 10; 83static unsigned int flushtimeout = 10;
84module_param(flushtimeout, int, 0600); 84module_param(flushtimeout, uint, 0600);
85MODULE_PARM_DESC(flushtimeout, "buffer flush timeout (hundredths of a second)"); 85MODULE_PARM_DESC(flushtimeout, "buffer flush timeout (hundredths of a second)");
86 86
87static unsigned int nflog = 1; 87static int nflog = 1;
88module_param(nflog, int, 0400); 88module_param(nflog, bool, 0400);
89MODULE_PARM_DESC(nflog, "register as internal netfilter logging module"); 89MODULE_PARM_DESC(nflog, "register as internal netfilter logging module");
90 90
91/* global data structures */ 91/* global data structures */
@@ -376,7 +376,7 @@ static int __init init(void)
376 376
377 DEBUGP("ipt_ULOG: init module\n"); 377 DEBUGP("ipt_ULOG: init module\n");
378 378
379 if (nlbufsiz >= 128*1024) { 379 if (nlbufsiz > 128*1024) {
380 printk("Netlink buffer has to be <= 128kB\n"); 380 printk("Netlink buffer has to be <= 128kB\n");
381 return -EINVAL; 381 return -EINVAL;
382 } 382 }
diff --git a/net/ipv4/netfilter/ipt_recent.c b/net/ipv4/netfilter/ipt_recent.c
index 261cbb4d4c49..5ddccb18c65e 100644
--- a/net/ipv4/netfilter/ipt_recent.c
+++ b/net/ipv4/netfilter/ipt_recent.c
@@ -24,10 +24,10 @@
24#define HASH_LOG 9 24#define HASH_LOG 9
25 25
26/* Defaults, these can be overridden on the module command-line. */ 26/* Defaults, these can be overridden on the module command-line. */
27static int ip_list_tot = 100; 27static unsigned int ip_list_tot = 100;
28static int ip_pkt_list_tot = 20; 28static unsigned int ip_pkt_list_tot = 20;
29static int ip_list_hash_size = 0; 29static unsigned int ip_list_hash_size = 0;
30static int ip_list_perms = 0644; 30static unsigned int ip_list_perms = 0644;
31#ifdef DEBUG 31#ifdef DEBUG
32static int debug = 1; 32static int debug = 1;
33#endif 33#endif
@@ -38,13 +38,13 @@ KERN_INFO RECENT_NAME " " RECENT_VER ": Stephen Frost <sfrost@snowman.net>. htt
38MODULE_AUTHOR("Stephen Frost <sfrost@snowman.net>"); 38MODULE_AUTHOR("Stephen Frost <sfrost@snowman.net>");
39MODULE_DESCRIPTION("IP tables recently seen matching module " RECENT_VER); 39MODULE_DESCRIPTION("IP tables recently seen matching module " RECENT_VER);
40MODULE_LICENSE("GPL"); 40MODULE_LICENSE("GPL");
41module_param(ip_list_tot, int, 0400); 41module_param(ip_list_tot, uint, 0400);
42module_param(ip_pkt_list_tot, int, 0400); 42module_param(ip_pkt_list_tot, uint, 0400);
43module_param(ip_list_hash_size, int, 0400); 43module_param(ip_list_hash_size, uint, 0400);
44module_param(ip_list_perms, int, 0400); 44module_param(ip_list_perms, uint, 0400);
45#ifdef DEBUG 45#ifdef DEBUG
46module_param(debug, int, 0600); 46module_param(debug, bool, 0600);
47MODULE_PARM_DESC(debug,"debugging level, defaults to 1"); 47MODULE_PARM_DESC(debug,"enable debugging output");
48#endif 48#endif
49MODULE_PARM_DESC(ip_list_tot,"number of IPs to remember per list"); 49MODULE_PARM_DESC(ip_list_tot,"number of IPs to remember per list");
50MODULE_PARM_DESC(ip_pkt_list_tot,"number of packets per IP to remember"); 50MODULE_PARM_DESC(ip_pkt_list_tot,"number of packets per IP to remember");
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index 8202c1c0afad..9bdbb7793971 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -22,6 +22,7 @@
22#include <linux/skbuff.h> 22#include <linux/skbuff.h>
23#include <linux/icmp.h> 23#include <linux/icmp.h>
24#include <linux/sysctl.h> 24#include <linux/sysctl.h>
25#include <net/route.h>
25#include <net/ip.h> 26#include <net/ip.h>
26 27
27#include <linux/netfilter_ipv4.h> 28#include <linux/netfilter_ipv4.h>
@@ -180,30 +181,6 @@ static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
180 return NF_ACCEPT; 181 return NF_ACCEPT;
181} 182}
182 183
183static unsigned int ipv4_refrag(unsigned int hooknum,
184 struct sk_buff **pskb,
185 const struct net_device *in,
186 const struct net_device *out,
187 int (*okfn)(struct sk_buff *))
188{
189 struct rtable *rt = (struct rtable *)(*pskb)->dst;
190
191 /* We've seen it coming out the other side: confirm */
192 if (ipv4_confirm(hooknum, pskb, in, out, okfn) != NF_ACCEPT)
193 return NF_DROP;
194
195 /* Local packets are never produced too large for their
196 interface. We degfragment them at LOCAL_OUT, however,
197 so we have to refragment them here. */
198 if ((*pskb)->len > dst_mtu(&rt->u.dst) &&
199 !skb_shinfo(*pskb)->tso_size) {
200 /* No hook can be after us, so this should be OK. */
201 ip_fragment(*pskb, okfn);
202 return NF_STOLEN;
203 }
204 return NF_ACCEPT;
205}
206
207static unsigned int ipv4_conntrack_in(unsigned int hooknum, 184static unsigned int ipv4_conntrack_in(unsigned int hooknum,
208 struct sk_buff **pskb, 185 struct sk_buff **pskb,
209 const struct net_device *in, 186 const struct net_device *in,
@@ -283,7 +260,7 @@ static struct nf_hook_ops ipv4_conntrack_helper_in_ops = {
283 260
284/* Refragmenter; last chance. */ 261/* Refragmenter; last chance. */
285static struct nf_hook_ops ipv4_conntrack_out_ops = { 262static struct nf_hook_ops ipv4_conntrack_out_ops = {
286 .hook = ipv4_refrag, 263 .hook = ipv4_confirm,
287 .owner = THIS_MODULE, 264 .owner = THIS_MODULE,
288 .pf = PF_INET, 265 .pf = PF_INET,
289 .hooknum = NF_IP_POST_ROUTING, 266 .hooknum = NF_IP_POST_ROUTING,
@@ -392,6 +369,48 @@ getorigdst(struct sock *sk, int optval, void __user *user, int *len)
392 return -ENOENT; 369 return -ENOENT;
393} 370}
394 371
372#if defined(CONFIG_NF_CT_NETLINK) || \
373 defined(CONFIG_NF_CT_NETLINK_MODULE)
374
375#include <linux/netfilter/nfnetlink.h>
376#include <linux/netfilter/nfnetlink_conntrack.h>
377
378static int ipv4_tuple_to_nfattr(struct sk_buff *skb,
379 const struct nf_conntrack_tuple *tuple)
380{
381 NFA_PUT(skb, CTA_IP_V4_SRC, sizeof(u_int32_t),
382 &tuple->src.u3.ip);
383 NFA_PUT(skb, CTA_IP_V4_DST, sizeof(u_int32_t),
384 &tuple->dst.u3.ip);
385 return 0;
386
387nfattr_failure:
388 return -1;
389}
390
391static const size_t cta_min_ip[CTA_IP_MAX] = {
392 [CTA_IP_V4_SRC-1] = sizeof(u_int32_t),
393 [CTA_IP_V4_DST-1] = sizeof(u_int32_t),
394};
395
396static int ipv4_nfattr_to_tuple(struct nfattr *tb[],
397 struct nf_conntrack_tuple *t)
398{
399 if (!tb[CTA_IP_V4_SRC-1] || !tb[CTA_IP_V4_DST-1])
400 return -EINVAL;
401
402 if (nfattr_bad_size(tb, CTA_IP_MAX, cta_min_ip))
403 return -EINVAL;
404
405 t->src.u3.ip =
406 *(u_int32_t *)NFA_DATA(tb[CTA_IP_V4_SRC-1]);
407 t->dst.u3.ip =
408 *(u_int32_t *)NFA_DATA(tb[CTA_IP_V4_DST-1]);
409
410 return 0;
411}
412#endif
413
395static struct nf_sockopt_ops so_getorigdst = { 414static struct nf_sockopt_ops so_getorigdst = {
396 .pf = PF_INET, 415 .pf = PF_INET,
397 .get_optmin = SO_ORIGINAL_DST, 416 .get_optmin = SO_ORIGINAL_DST,
@@ -408,6 +427,11 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 = {
408 .print_conntrack = ipv4_print_conntrack, 427 .print_conntrack = ipv4_print_conntrack,
409 .prepare = ipv4_prepare, 428 .prepare = ipv4_prepare,
410 .get_features = ipv4_get_features, 429 .get_features = ipv4_get_features,
430#if defined(CONFIG_NF_CT_NETLINK) || \
431 defined(CONFIG_NF_CT_NETLINK_MODULE)
432 .tuple_to_nfattr = ipv4_tuple_to_nfattr,
433 .nfattr_to_tuple = ipv4_nfattr_to_tuple,
434#endif
411 .me = THIS_MODULE, 435 .me = THIS_MODULE,
412}; 436};
413 437
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
index 7ddb5c08f7b8..52dc175be39a 100644
--- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
@@ -50,20 +50,21 @@ static int icmp_pkt_to_tuple(const struct sk_buff *skb,
50 return 1; 50 return 1;
51} 51}
52 52
53/* Add 1; spaces filled with 0. */
54static const u_int8_t invmap[] = {
55 [ICMP_ECHO] = ICMP_ECHOREPLY + 1,
56 [ICMP_ECHOREPLY] = ICMP_ECHO + 1,
57 [ICMP_TIMESTAMP] = ICMP_TIMESTAMPREPLY + 1,
58 [ICMP_TIMESTAMPREPLY] = ICMP_TIMESTAMP + 1,
59 [ICMP_INFO_REQUEST] = ICMP_INFO_REPLY + 1,
60 [ICMP_INFO_REPLY] = ICMP_INFO_REQUEST + 1,
61 [ICMP_ADDRESS] = ICMP_ADDRESSREPLY + 1,
62 [ICMP_ADDRESSREPLY] = ICMP_ADDRESS + 1
63};
64
53static int icmp_invert_tuple(struct nf_conntrack_tuple *tuple, 65static int icmp_invert_tuple(struct nf_conntrack_tuple *tuple,
54 const struct nf_conntrack_tuple *orig) 66 const struct nf_conntrack_tuple *orig)
55{ 67{
56 /* Add 1; spaces filled with 0. */
57 static u_int8_t invmap[]
58 = { [ICMP_ECHO] = ICMP_ECHOREPLY + 1,
59 [ICMP_ECHOREPLY] = ICMP_ECHO + 1,
60 [ICMP_TIMESTAMP] = ICMP_TIMESTAMPREPLY + 1,
61 [ICMP_TIMESTAMPREPLY] = ICMP_TIMESTAMP + 1,
62 [ICMP_INFO_REQUEST] = ICMP_INFO_REPLY + 1,
63 [ICMP_INFO_REPLY] = ICMP_INFO_REQUEST + 1,
64 [ICMP_ADDRESS] = ICMP_ADDRESSREPLY + 1,
65 [ICMP_ADDRESSREPLY] = ICMP_ADDRESS + 1};
66
67 if (orig->dst.u.icmp.type >= sizeof(invmap) 68 if (orig->dst.u.icmp.type >= sizeof(invmap)
68 || !invmap[orig->dst.u.icmp.type]) 69 || !invmap[orig->dst.u.icmp.type])
69 return 0; 70 return 0;
@@ -120,11 +121,12 @@ static int icmp_packet(struct nf_conn *ct,
120static int icmp_new(struct nf_conn *conntrack, 121static int icmp_new(struct nf_conn *conntrack,
121 const struct sk_buff *skb, unsigned int dataoff) 122 const struct sk_buff *skb, unsigned int dataoff)
122{ 123{
123 static u_int8_t valid_new[] 124 static const u_int8_t valid_new[] = {
124 = { [ICMP_ECHO] = 1, 125 [ICMP_ECHO] = 1,
125 [ICMP_TIMESTAMP] = 1, 126 [ICMP_TIMESTAMP] = 1,
126 [ICMP_INFO_REQUEST] = 1, 127 [ICMP_INFO_REQUEST] = 1,
127 [ICMP_ADDRESS] = 1 }; 128 [ICMP_ADDRESS] = 1
129 };
128 130
129 if (conntrack->tuplehash[0].tuple.dst.u.icmp.type >= sizeof(valid_new) 131 if (conntrack->tuplehash[0].tuple.dst.u.icmp.type >= sizeof(valid_new)
130 || !valid_new[conntrack->tuplehash[0].tuple.dst.u.icmp.type]) { 132 || !valid_new[conntrack->tuplehash[0].tuple.dst.u.icmp.type]) {
@@ -168,7 +170,7 @@ icmp_error_message(struct sk_buff *skb,
168 return -NF_ACCEPT; 170 return -NF_ACCEPT;
169 } 171 }
170 172
171 innerproto = nf_ct_find_proto(PF_INET, inside->ip.protocol); 173 innerproto = __nf_ct_proto_find(PF_INET, inside->ip.protocol);
172 dataoff = skb->nh.iph->ihl*4 + sizeof(inside->icmp); 174 dataoff = skb->nh.iph->ihl*4 + sizeof(inside->icmp);
173 /* Are they talking about one of our connections? */ 175 /* Are they talking about one of our connections? */
174 if (!nf_ct_get_tuple(skb, dataoff, dataoff + inside->ip.ihl*4, PF_INET, 176 if (!nf_ct_get_tuple(skb, dataoff, dataoff + inside->ip.ihl*4, PF_INET,
@@ -281,6 +283,60 @@ checksum_skipped:
281 return icmp_error_message(skb, ctinfo, hooknum); 283 return icmp_error_message(skb, ctinfo, hooknum);
282} 284}
283 285
286#if defined(CONFIG_NF_CT_NETLINK) || \
287 defined(CONFIG_NF_CT_NETLINK_MODULE)
288
289#include <linux/netfilter/nfnetlink.h>
290#include <linux/netfilter/nfnetlink_conntrack.h>
291
292static int icmp_tuple_to_nfattr(struct sk_buff *skb,
293 const struct nf_conntrack_tuple *t)
294{
295 NFA_PUT(skb, CTA_PROTO_ICMP_ID, sizeof(u_int16_t),
296 &t->src.u.icmp.id);
297 NFA_PUT(skb, CTA_PROTO_ICMP_TYPE, sizeof(u_int8_t),
298 &t->dst.u.icmp.type);
299 NFA_PUT(skb, CTA_PROTO_ICMP_CODE, sizeof(u_int8_t),
300 &t->dst.u.icmp.code);
301
302 return 0;
303
304nfattr_failure:
305 return -1;
306}
307
308static const size_t cta_min_proto[CTA_PROTO_MAX] = {
309 [CTA_PROTO_ICMP_TYPE-1] = sizeof(u_int8_t),
310 [CTA_PROTO_ICMP_CODE-1] = sizeof(u_int8_t),
311 [CTA_PROTO_ICMP_ID-1] = sizeof(u_int16_t)
312};
313
314static int icmp_nfattr_to_tuple(struct nfattr *tb[],
315 struct nf_conntrack_tuple *tuple)
316{
317 if (!tb[CTA_PROTO_ICMP_TYPE-1]
318 || !tb[CTA_PROTO_ICMP_CODE-1]
319 || !tb[CTA_PROTO_ICMP_ID-1])
320 return -EINVAL;
321
322 if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto))
323 return -EINVAL;
324
325 tuple->dst.u.icmp.type =
326 *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_TYPE-1]);
327 tuple->dst.u.icmp.code =
328 *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_CODE-1]);
329 tuple->src.u.icmp.id =
330 *(u_int16_t *)NFA_DATA(tb[CTA_PROTO_ICMP_ID-1]);
331
332 if (tuple->dst.u.icmp.type >= sizeof(invmap)
333 || !invmap[tuple->dst.u.icmp.type])
334 return -EINVAL;
335
336 return 0;
337}
338#endif
339
284struct nf_conntrack_protocol nf_conntrack_protocol_icmp = 340struct nf_conntrack_protocol nf_conntrack_protocol_icmp =
285{ 341{
286 .list = { NULL, NULL }, 342 .list = { NULL, NULL },
@@ -295,7 +351,12 @@ struct nf_conntrack_protocol nf_conntrack_protocol_icmp =
295 .new = icmp_new, 351 .new = icmp_new,
296 .error = icmp_error, 352 .error = icmp_error,
297 .destroy = NULL, 353 .destroy = NULL,
298 .me = NULL 354 .me = NULL,
355#if defined(CONFIG_NF_CT_NETLINK) || \
356 defined(CONFIG_NF_CT_NETLINK_MODULE)
357 .tuple_to_nfattr = icmp_tuple_to_nfattr,
358 .nfattr_to_tuple = icmp_nfattr_to_tuple,
359#endif
299}; 360};
300 361
301EXPORT_SYMBOL(nf_conntrack_protocol_icmp); 362EXPORT_SYMBOL(nf_conntrack_protocol_icmp);
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index ea43ef1d94a7..925b42d48347 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -119,13 +119,14 @@ static LIST_HEAD(ip6t_tables);
119#define up(x) do { printk("UP:%u:" #x "\n", __LINE__); up(x); } while(0) 119#define up(x) do { printk("UP:%u:" #x "\n", __LINE__); up(x); } while(0)
120#endif 120#endif
121 121
122static int ip6_masked_addrcmp(struct in6_addr addr1, struct in6_addr mask, 122int
123 struct in6_addr addr2) 123ip6_masked_addrcmp(const struct in6_addr *addr1, const struct in6_addr *mask,
124 const struct in6_addr *addr2)
124{ 125{
125 int i; 126 int i;
126 for( i = 0; i < 16; i++){ 127 for( i = 0; i < 16; i++){
127 if((addr1.s6_addr[i] & mask.s6_addr[i]) != 128 if((addr1->s6_addr[i] & mask->s6_addr[i]) !=
128 (addr2.s6_addr[i] & mask.s6_addr[i])) 129 (addr2->s6_addr[i] & mask->s6_addr[i]))
129 return 1; 130 return 1;
130 } 131 }
131 return 0; 132 return 0;
@@ -159,10 +160,10 @@ ip6_packet_match(const struct sk_buff *skb,
159 160
160#define FWINV(bool,invflg) ((bool) ^ !!(ip6info->invflags & invflg)) 161#define FWINV(bool,invflg) ((bool) ^ !!(ip6info->invflags & invflg))
161 162
162 if (FWINV(ip6_masked_addrcmp(ipv6->saddr,ip6info->smsk,ip6info->src), 163 if (FWINV(ip6_masked_addrcmp(&ipv6->saddr, &ip6info->smsk,
163 IP6T_INV_SRCIP) 164 &ip6info->src), IP6T_INV_SRCIP)
164 || FWINV(ip6_masked_addrcmp(ipv6->daddr,ip6info->dmsk,ip6info->dst), 165 || FWINV(ip6_masked_addrcmp(&ipv6->daddr, &ip6info->dmsk,
165 IP6T_INV_DSTIP)) { 166 &ip6info->dst), IP6T_INV_DSTIP)) {
166 dprintf("Source or dest mismatch.\n"); 167 dprintf("Source or dest mismatch.\n");
167/* 168/*
168 dprintf("SRC: %u. Mask: %u. Target: %u.%s\n", ip->saddr, 169 dprintf("SRC: %u. Mask: %u. Target: %u.%s\n", ip->saddr,
@@ -205,69 +206,21 @@ ip6_packet_match(const struct sk_buff *skb,
205 206
206 /* look for the desired protocol header */ 207 /* look for the desired protocol header */
207 if((ip6info->flags & IP6T_F_PROTO)) { 208 if((ip6info->flags & IP6T_F_PROTO)) {
208 u_int8_t currenthdr = ipv6->nexthdr; 209 int protohdr;
209 struct ipv6_opt_hdr _hdr, *hp; 210 unsigned short _frag_off;
210 u_int16_t ptr; /* Header offset in skb */
211 u_int16_t hdrlen; /* Header */
212 u_int16_t _fragoff = 0, *fp = NULL;
213
214 ptr = IPV6_HDR_LEN;
215
216 while (ip6t_ext_hdr(currenthdr)) {
217 /* Is there enough space for the next ext header? */
218 if (skb->len - ptr < IPV6_OPTHDR_LEN)
219 return 0;
220
221 /* NONE or ESP: there isn't protocol part */
222 /* If we want to count these packets in '-p all',
223 * we will change the return 0 to 1*/
224 if ((currenthdr == IPPROTO_NONE) ||
225 (currenthdr == IPPROTO_ESP))
226 break;
227 211
228 hp = skb_header_pointer(skb, ptr, sizeof(_hdr), &_hdr); 212 protohdr = ipv6_find_hdr(skb, protoff, -1, &_frag_off);
229 BUG_ON(hp == NULL); 213 if (protohdr < 0)
230 214 return 0;
231 /* Size calculation */
232 if (currenthdr == IPPROTO_FRAGMENT) {
233 fp = skb_header_pointer(skb,
234 ptr+offsetof(struct frag_hdr,
235 frag_off),
236 sizeof(_fragoff),
237 &_fragoff);
238 if (fp == NULL)
239 return 0;
240
241 _fragoff = ntohs(*fp) & ~0x7;
242 hdrlen = 8;
243 } else if (currenthdr == IPPROTO_AH)
244 hdrlen = (hp->hdrlen+2)<<2;
245 else
246 hdrlen = ipv6_optlen(hp);
247
248 currenthdr = hp->nexthdr;
249 ptr += hdrlen;
250 /* ptr is too large */
251 if ( ptr > skb->len )
252 return 0;
253 if (_fragoff) {
254 if (ip6t_ext_hdr(currenthdr))
255 return 0;
256 break;
257 }
258 }
259
260 *protoff = ptr;
261 *fragoff = _fragoff;
262 215
263 /* currenthdr contains the protocol header */ 216 *fragoff = _frag_off;
264 217
265 dprintf("Packet protocol %hi ?= %s%hi.\n", 218 dprintf("Packet protocol %hi ?= %s%hi.\n",
266 currenthdr, 219 protohdr,
267 ip6info->invflags & IP6T_INV_PROTO ? "!":"", 220 ip6info->invflags & IP6T_INV_PROTO ? "!":"",
268 ip6info->proto); 221 ip6info->proto);
269 222
270 if (ip6info->proto == currenthdr) { 223 if (ip6info->proto == protohdr) {
271 if(ip6info->invflags & IP6T_INV_PROTO) { 224 if(ip6info->invflags & IP6T_INV_PROTO) {
272 return 0; 225 return 0;
273 } 226 }
@@ -2098,26 +2051,39 @@ static void __exit fini(void)
2098} 2051}
2099 2052
2100/* 2053/*
2101 * find specified header up to transport protocol header. 2054 * find the offset to specified header or the protocol number of last header
2102 * If found target header, the offset to the header is set to *offset 2055 * if target < 0. "last header" is transport protocol header, ESP, or
2103 * and return 0. otherwise, return -1. 2056 * "No next header".
2057 *
2058 * If target header is found, its offset is set in *offset and return protocol
2059 * number. Otherwise, return -1.
2060 *
2061 * Note that non-1st fragment is special case that "the protocol number
2062 * of last header" is "next header" field in Fragment header. In this case,
2063 * *offset is meaningless and fragment offset is stored in *fragoff if fragoff
2064 * isn't NULL.
2104 * 2065 *
2105 * Notes: - non-1st Fragment Header isn't skipped.
2106 * - ESP header isn't skipped.
2107 * - The target header may be trancated.
2108 */ 2066 */
2109int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, u8 target) 2067int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
2068 int target, unsigned short *fragoff)
2110{ 2069{
2111 unsigned int start = (u8*)(skb->nh.ipv6h + 1) - skb->data; 2070 unsigned int start = (u8*)(skb->nh.ipv6h + 1) - skb->data;
2112 u8 nexthdr = skb->nh.ipv6h->nexthdr; 2071 u8 nexthdr = skb->nh.ipv6h->nexthdr;
2113 unsigned int len = skb->len - start; 2072 unsigned int len = skb->len - start;
2114 2073
2074 if (fragoff)
2075 *fragoff = 0;
2076
2115 while (nexthdr != target) { 2077 while (nexthdr != target) {
2116 struct ipv6_opt_hdr _hdr, *hp; 2078 struct ipv6_opt_hdr _hdr, *hp;
2117 unsigned int hdrlen; 2079 unsigned int hdrlen;
2118 2080
2119 if ((!ipv6_ext_hdr(nexthdr)) || nexthdr == NEXTHDR_NONE) 2081 if ((!ipv6_ext_hdr(nexthdr)) || nexthdr == NEXTHDR_NONE) {
2082 if (target < 0)
2083 break;
2120 return -1; 2084 return -1;
2085 }
2086
2121 hp = skb_header_pointer(skb, start, sizeof(_hdr), &_hdr); 2087 hp = skb_header_pointer(skb, start, sizeof(_hdr), &_hdr);
2122 if (hp == NULL) 2088 if (hp == NULL)
2123 return -1; 2089 return -1;
@@ -2131,8 +2097,17 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, u8 target)
2131 if (fp == NULL) 2097 if (fp == NULL)
2132 return -1; 2098 return -1;
2133 2099
2134 if (ntohs(*fp) & ~0x7) 2100 _frag_off = ntohs(*fp) & ~0x7;
2101 if (_frag_off) {
2102 if (target < 0 &&
2103 ((!ipv6_ext_hdr(hp->nexthdr)) ||
2104 nexthdr == NEXTHDR_NONE)) {
2105 if (fragoff)
2106 *fragoff = _frag_off;
2107 return hp->nexthdr;
2108 }
2135 return -1; 2109 return -1;
2110 }
2136 hdrlen = 8; 2111 hdrlen = 8;
2137 } else if (nexthdr == NEXTHDR_AUTH) 2112 } else if (nexthdr == NEXTHDR_AUTH)
2138 hdrlen = (hp->hdrlen + 2) << 2; 2113 hdrlen = (hp->hdrlen + 2) << 2;
@@ -2145,7 +2120,7 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, u8 target)
2145 } 2120 }
2146 2121
2147 *offset = start; 2122 *offset = start;
2148 return 0; 2123 return nexthdr;
2149} 2124}
2150 2125
2151EXPORT_SYMBOL(ip6t_register_table); 2126EXPORT_SYMBOL(ip6t_register_table);
@@ -2157,6 +2132,7 @@ EXPORT_SYMBOL(ip6t_register_target);
2157EXPORT_SYMBOL(ip6t_unregister_target); 2132EXPORT_SYMBOL(ip6t_unregister_target);
2158EXPORT_SYMBOL(ip6t_ext_hdr); 2133EXPORT_SYMBOL(ip6t_ext_hdr);
2159EXPORT_SYMBOL(ipv6_find_hdr); 2134EXPORT_SYMBOL(ipv6_find_hdr);
2135EXPORT_SYMBOL(ip6_masked_addrcmp);
2160 2136
2161module_init(init); 2137module_init(init);
2162module_exit(fini); 2138module_exit(fini);
diff --git a/net/ipv6/netfilter/ip6t_ah.c b/net/ipv6/netfilter/ip6t_ah.c
index 268918d5deea..f5c1a7ff4a1f 100644
--- a/net/ipv6/netfilter/ip6t_ah.c
+++ b/net/ipv6/netfilter/ip6t_ah.c
@@ -54,7 +54,7 @@ match(const struct sk_buff *skb,
54 unsigned int ptr; 54 unsigned int ptr;
55 unsigned int hdrlen = 0; 55 unsigned int hdrlen = 0;
56 56
57 if (ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH) < 0) 57 if (ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL) < 0)
58 return 0; 58 return 0;
59 59
60 ah = skb_header_pointer(skb, ptr, sizeof(_ah), &_ah); 60 ah = skb_header_pointer(skb, ptr, sizeof(_ah), &_ah);
diff --git a/net/ipv6/netfilter/ip6t_dst.c b/net/ipv6/netfilter/ip6t_dst.c
index c450a635e54b..48cf5f9efc95 100644
--- a/net/ipv6/netfilter/ip6t_dst.c
+++ b/net/ipv6/netfilter/ip6t_dst.c
@@ -71,9 +71,9 @@ match(const struct sk_buff *skb,
71 unsigned int optlen; 71 unsigned int optlen;
72 72
73#if HOPBYHOP 73#if HOPBYHOP
74 if (ipv6_find_hdr(skb, &ptr, NEXTHDR_HOP) < 0) 74 if (ipv6_find_hdr(skb, &ptr, NEXTHDR_HOP, NULL) < 0)
75#else 75#else
76 if (ipv6_find_hdr(skb, &ptr, NEXTHDR_DEST) < 0) 76 if (ipv6_find_hdr(skb, &ptr, NEXTHDR_DEST, NULL) < 0)
77#endif 77#endif
78 return 0; 78 return 0;
79 79
diff --git a/net/ipv6/netfilter/ip6t_esp.c b/net/ipv6/netfilter/ip6t_esp.c
index 65937de1b58c..e1828f6d0a40 100644
--- a/net/ipv6/netfilter/ip6t_esp.c
+++ b/net/ipv6/netfilter/ip6t_esp.c
@@ -56,7 +56,7 @@ match(const struct sk_buff *skb,
56 /* Make sure this isn't an evil packet */ 56 /* Make sure this isn't an evil packet */
57 /*DEBUGP("ipv6_esp entered \n");*/ 57 /*DEBUGP("ipv6_esp entered \n");*/
58 58
59 if (ipv6_find_hdr(skb, &ptr, NEXTHDR_ESP) < 0) 59 if (ipv6_find_hdr(skb, &ptr, NEXTHDR_ESP, NULL) < 0)
60 return 0; 60 return 0;
61 61
62 eh = skb_header_pointer(skb, ptr, sizeof(_esp), &_esp); 62 eh = skb_header_pointer(skb, ptr, sizeof(_esp), &_esp);
diff --git a/net/ipv6/netfilter/ip6t_frag.c b/net/ipv6/netfilter/ip6t_frag.c
index 085d5f8eea29..d1549b268669 100644
--- a/net/ipv6/netfilter/ip6t_frag.c
+++ b/net/ipv6/netfilter/ip6t_frag.c
@@ -52,7 +52,7 @@ match(const struct sk_buff *skb,
52 const struct ip6t_frag *fraginfo = matchinfo; 52 const struct ip6t_frag *fraginfo = matchinfo;
53 unsigned int ptr; 53 unsigned int ptr;
54 54
55 if (ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT) < 0) 55 if (ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL) < 0)
56 return 0; 56 return 0;
57 57
58 fh = skb_header_pointer(skb, ptr, sizeof(_frag), &_frag); 58 fh = skb_header_pointer(skb, ptr, sizeof(_frag), &_frag);
diff --git a/net/ipv6/netfilter/ip6t_hbh.c b/net/ipv6/netfilter/ip6t_hbh.c
index 1d09485111d0..e3bc8e2700e7 100644
--- a/net/ipv6/netfilter/ip6t_hbh.c
+++ b/net/ipv6/netfilter/ip6t_hbh.c
@@ -71,9 +71,9 @@ match(const struct sk_buff *skb,
71 unsigned int optlen; 71 unsigned int optlen;
72 72
73#if HOPBYHOP 73#if HOPBYHOP
74 if (ipv6_find_hdr(skb, &ptr, NEXTHDR_HOP) < 0) 74 if (ipv6_find_hdr(skb, &ptr, NEXTHDR_HOP, NULL) < 0)
75#else 75#else
76 if (ipv6_find_hdr(skb, &ptr, NEXTHDR_DEST) < 0) 76 if (ipv6_find_hdr(skb, &ptr, NEXTHDR_DEST, NULL) < 0)
77#endif 77#endif
78 return 0; 78 return 0;
79 79
diff --git a/net/ipv6/netfilter/ip6t_rt.c b/net/ipv6/netfilter/ip6t_rt.c
index beb2fd5cebbb..c1e770e45543 100644
--- a/net/ipv6/netfilter/ip6t_rt.c
+++ b/net/ipv6/netfilter/ip6t_rt.c
@@ -58,7 +58,7 @@ match(const struct sk_buff *skb,
58 unsigned int ret = 0; 58 unsigned int ret = 0;
59 struct in6_addr *ap, _addr; 59 struct in6_addr *ap, _addr;
60 60
61 if (ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING) < 0) 61 if (ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL) < 0)
62 return 0; 62 return 0;
63 63
64 rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route); 64 rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route);
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 753a3ae8502b..704fbbe74874 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -401,6 +401,48 @@ static ctl_table nf_ct_net_table[] = {
401}; 401};
402#endif 402#endif
403 403
404#if defined(CONFIG_NF_CT_NETLINK) || \
405 defined(CONFIG_NF_CT_NETLINK_MODULE)
406
407#include <linux/netfilter/nfnetlink.h>
408#include <linux/netfilter/nfnetlink_conntrack.h>
409
410static int ipv6_tuple_to_nfattr(struct sk_buff *skb,
411 const struct nf_conntrack_tuple *tuple)
412{
413 NFA_PUT(skb, CTA_IP_V6_SRC, sizeof(u_int32_t) * 4,
414 &tuple->src.u3.ip6);
415 NFA_PUT(skb, CTA_IP_V6_DST, sizeof(u_int32_t) * 4,
416 &tuple->dst.u3.ip6);
417 return 0;
418
419nfattr_failure:
420 return -1;
421}
422
423static const size_t cta_min_ip[CTA_IP_MAX] = {
424 [CTA_IP_V6_SRC-1] = sizeof(u_int32_t)*4,
425 [CTA_IP_V6_DST-1] = sizeof(u_int32_t)*4,
426};
427
428static int ipv6_nfattr_to_tuple(struct nfattr *tb[],
429 struct nf_conntrack_tuple *t)
430{
431 if (!tb[CTA_IP_V6_SRC-1] || !tb[CTA_IP_V6_DST-1])
432 return -EINVAL;
433
434 if (nfattr_bad_size(tb, CTA_IP_MAX, cta_min_ip))
435 return -EINVAL;
436
437 memcpy(&t->src.u3.ip6, NFA_DATA(tb[CTA_IP_V6_SRC-1]),
438 sizeof(u_int32_t) * 4);
439 memcpy(&t->dst.u3.ip6, NFA_DATA(tb[CTA_IP_V6_DST-1]),
440 sizeof(u_int32_t) * 4);
441
442 return 0;
443}
444#endif
445
404struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 = { 446struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 = {
405 .l3proto = PF_INET6, 447 .l3proto = PF_INET6,
406 .name = "ipv6", 448 .name = "ipv6",
@@ -409,6 +451,11 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 = {
409 .print_tuple = ipv6_print_tuple, 451 .print_tuple = ipv6_print_tuple,
410 .print_conntrack = ipv6_print_conntrack, 452 .print_conntrack = ipv6_print_conntrack,
411 .prepare = ipv6_prepare, 453 .prepare = ipv6_prepare,
454#if defined(CONFIG_NF_CT_NETLINK) || \
455 defined(CONFIG_NF_CT_NETLINK_MODULE)
456 .tuple_to_nfattr = ipv6_tuple_to_nfattr,
457 .nfattr_to_tuple = ipv6_nfattr_to_tuple,
458#endif
412 .get_features = ipv6_get_features, 459 .get_features = ipv6_get_features,
413 .me = THIS_MODULE, 460 .me = THIS_MODULE,
414}; 461};
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
index a7e03cfacd06..09945c333055 100644
--- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -57,17 +57,17 @@ static int icmpv6_pkt_to_tuple(const struct sk_buff *skb,
57 return 1; 57 return 1;
58} 58}
59 59
60/* Add 1; spaces filled with 0. */
61static u_int8_t invmap[] = {
62 [ICMPV6_ECHO_REQUEST - 128] = ICMPV6_ECHO_REPLY + 1,
63 [ICMPV6_ECHO_REPLY - 128] = ICMPV6_ECHO_REQUEST + 1,
64 [ICMPV6_NI_QUERY - 128] = ICMPV6_NI_QUERY + 1,
65 [ICMPV6_NI_REPLY - 128] = ICMPV6_NI_REPLY +1
66};
67
60static int icmpv6_invert_tuple(struct nf_conntrack_tuple *tuple, 68static int icmpv6_invert_tuple(struct nf_conntrack_tuple *tuple,
61 const struct nf_conntrack_tuple *orig) 69 const struct nf_conntrack_tuple *orig)
62{ 70{
63 /* Add 1; spaces filled with 0. */
64 static u_int8_t invmap[] = {
65 [ICMPV6_ECHO_REQUEST - 128] = ICMPV6_ECHO_REPLY + 1,
66 [ICMPV6_ECHO_REPLY - 128] = ICMPV6_ECHO_REQUEST + 1,
67 [ICMPV6_NI_QUERY - 128] = ICMPV6_NI_QUERY + 1,
68 [ICMPV6_NI_REPLY - 128] = ICMPV6_NI_REPLY +1
69 };
70
71 int type = orig->dst.u.icmp.type - 128; 71 int type = orig->dst.u.icmp.type - 128;
72 if (type < 0 || type >= sizeof(invmap) || !invmap[type]) 72 if (type < 0 || type >= sizeof(invmap) || !invmap[type])
73 return 0; 73 return 0;
@@ -185,7 +185,7 @@ icmpv6_error_message(struct sk_buff *skb,
185 return -NF_ACCEPT; 185 return -NF_ACCEPT;
186 } 186 }
187 187
188 inproto = nf_ct_find_proto(PF_INET6, inprotonum); 188 inproto = __nf_ct_proto_find(PF_INET6, inprotonum);
189 189
190 /* Are they talking about one of our connections? */ 190 /* Are they talking about one of our connections? */
191 if (!nf_ct_get_tuple(skb, inip6off, inprotoff, PF_INET6, inprotonum, 191 if (!nf_ct_get_tuple(skb, inip6off, inprotoff, PF_INET6, inprotonum,
@@ -255,6 +255,60 @@ skipped:
255 return icmpv6_error_message(skb, dataoff, ctinfo, hooknum); 255 return icmpv6_error_message(skb, dataoff, ctinfo, hooknum);
256} 256}
257 257
258#if defined(CONFIG_NF_CT_NETLINK) || \
259 defined(CONFIG_NF_CT_NETLINK_MODULE)
260
261#include <linux/netfilter/nfnetlink.h>
262#include <linux/netfilter/nfnetlink_conntrack.h>
263static int icmpv6_tuple_to_nfattr(struct sk_buff *skb,
264 const struct nf_conntrack_tuple *t)
265{
266 NFA_PUT(skb, CTA_PROTO_ICMPV6_ID, sizeof(u_int16_t),
267 &t->src.u.icmp.id);
268 NFA_PUT(skb, CTA_PROTO_ICMPV6_TYPE, sizeof(u_int8_t),
269 &t->dst.u.icmp.type);
270 NFA_PUT(skb, CTA_PROTO_ICMPV6_CODE, sizeof(u_int8_t),
271 &t->dst.u.icmp.code);
272
273 return 0;
274
275nfattr_failure:
276 return -1;
277}
278
279static const size_t cta_min_proto[CTA_PROTO_MAX] = {
280 [CTA_PROTO_ICMPV6_TYPE-1] = sizeof(u_int8_t),
281 [CTA_PROTO_ICMPV6_CODE-1] = sizeof(u_int8_t),
282 [CTA_PROTO_ICMPV6_ID-1] = sizeof(u_int16_t)
283};
284
285static int icmpv6_nfattr_to_tuple(struct nfattr *tb[],
286 struct nf_conntrack_tuple *tuple)
287{
288 if (!tb[CTA_PROTO_ICMPV6_TYPE-1]
289 || !tb[CTA_PROTO_ICMPV6_CODE-1]
290 || !tb[CTA_PROTO_ICMPV6_ID-1])
291 return -EINVAL;
292
293 if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto))
294 return -EINVAL;
295
296 tuple->dst.u.icmp.type =
297 *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMPV6_TYPE-1]);
298 tuple->dst.u.icmp.code =
299 *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMPV6_CODE-1]);
300 tuple->src.u.icmp.id =
301 *(u_int16_t *)NFA_DATA(tb[CTA_PROTO_ICMPV6_ID-1]);
302
303 if (tuple->dst.u.icmp.type < 128
304 || tuple->dst.u.icmp.type - 128 >= sizeof(invmap)
305 || !invmap[tuple->dst.u.icmp.type - 128])
306 return -EINVAL;
307
308 return 0;
309}
310#endif
311
258struct nf_conntrack_protocol nf_conntrack_protocol_icmpv6 = 312struct nf_conntrack_protocol nf_conntrack_protocol_icmpv6 =
259{ 313{
260 .l3proto = PF_INET6, 314 .l3proto = PF_INET6,
@@ -267,6 +321,11 @@ struct nf_conntrack_protocol nf_conntrack_protocol_icmpv6 =
267 .packet = icmpv6_packet, 321 .packet = icmpv6_packet,
268 .new = icmpv6_new, 322 .new = icmpv6_new,
269 .error = icmpv6_error, 323 .error = icmpv6_error,
324#if defined(CONFIG_NF_CT_NETLINK) || \
325 defined(CONFIG_NF_CT_NETLINK_MODULE)
326 .tuple_to_nfattr = icmpv6_tuple_to_nfattr,
327 .nfattr_to_tuple = icmpv6_nfattr_to_tuple,
328#endif
270}; 329};
271 330
272EXPORT_SYMBOL(nf_conntrack_protocol_icmpv6); 331EXPORT_SYMBOL(nf_conntrack_protocol_icmpv6);
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index c3123c9e1a8e..577d49732b0f 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -33,6 +33,7 @@
33#include <asm/uaccess.h> 33#include <asm/uaccess.h>
34#include <linux/init.h> 34#include <linux/init.h>
35#include <linux/netfilter_ipv4.h> 35#include <linux/netfilter_ipv4.h>
36#include <linux/if_ether.h>
36 37
37#include <net/sock.h> 38#include <net/sock.h>
38#include <net/snmp.h> 39#include <net/snmp.h>
@@ -720,7 +721,7 @@ static void ipip6_tunnel_setup(struct net_device *dev)
720 721
721 dev->type = ARPHRD_SIT; 722 dev->type = ARPHRD_SIT;
722 dev->hard_header_len = LL_MAX_HEADER + sizeof(struct iphdr); 723 dev->hard_header_len = LL_MAX_HEADER + sizeof(struct iphdr);
723 dev->mtu = 1500 - sizeof(struct iphdr); 724 dev->mtu = ETH_DATA_LEN - sizeof(struct iphdr);
724 dev->flags = IFF_NOARP; 725 dev->flags = IFF_NOARP;
725 dev->iflink = 0; 726 dev->iflink = 0;
726 dev->addr_len = 4; 727 dev->addr_len = 4;
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 794c41d19b28..7d55f9cbd853 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -95,4 +95,11 @@ config NF_CONNTRACK_FTP
95 95
96 To compile it as a module, choose M here. If unsure, say N. 96 To compile it as a module, choose M here. If unsure, say N.
97 97
98config NF_CT_NETLINK
99 tristate 'Connection tracking netlink interface (EXPERIMENTAL)'
100 depends on EXPERIMENTAL && NF_CONNTRACK && NETFILTER_NETLINK
101 depends on NF_CONNTRACK!=y || NETFILTER_NETLINK!=m
102 help
103 This option enables support for a netlink-based userspace interface
104
98endmenu 105endmenu
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 55f019ad2c08..cb2183145c37 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -13,3 +13,6 @@ obj-$(CONFIG_NF_CONNTRACK_FTP) += nf_conntrack_ftp.o
13 13
14# SCTP protocol connection tracking 14# SCTP protocol connection tracking
15obj-$(CONFIG_NF_CT_PROTO_SCTP) += nf_conntrack_proto_sctp.o 15obj-$(CONFIG_NF_CT_PROTO_SCTP) += nf_conntrack_proto_sctp.o
16
17# netlink interface for nf_conntrack
18obj-$(CONFIG_NF_CT_NETLINK) += nf_conntrack_netlink.o
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index a7c7b490cf22..62bb509f05d4 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -82,6 +82,8 @@ unsigned int nf_ct_log_invalid;
82static LIST_HEAD(unconfirmed); 82static LIST_HEAD(unconfirmed);
83static int nf_conntrack_vmalloc; 83static int nf_conntrack_vmalloc;
84 84
85static unsigned int nf_conntrack_next_id = 1;
86static unsigned int nf_conntrack_expect_next_id = 1;
85#ifdef CONFIG_NF_CONNTRACK_EVENTS 87#ifdef CONFIG_NF_CONNTRACK_EVENTS
86struct notifier_block *nf_conntrack_chain; 88struct notifier_block *nf_conntrack_chain;
87struct notifier_block *nf_conntrack_expect_chain; 89struct notifier_block *nf_conntrack_expect_chain;
@@ -184,7 +186,7 @@ DECLARE_MUTEX(nf_ct_cache_mutex);
184 186
185extern struct nf_conntrack_protocol nf_conntrack_generic_protocol; 187extern struct nf_conntrack_protocol nf_conntrack_generic_protocol;
186struct nf_conntrack_protocol * 188struct nf_conntrack_protocol *
187nf_ct_find_proto(u_int16_t l3proto, u_int8_t protocol) 189__nf_ct_proto_find(u_int16_t l3proto, u_int8_t protocol)
188{ 190{
189 if (unlikely(nf_ct_protos[l3proto] == NULL)) 191 if (unlikely(nf_ct_protos[l3proto] == NULL))
190 return &nf_conntrack_generic_protocol; 192 return &nf_conntrack_generic_protocol;
@@ -192,6 +194,50 @@ nf_ct_find_proto(u_int16_t l3proto, u_int8_t protocol)
192 return nf_ct_protos[l3proto][protocol]; 194 return nf_ct_protos[l3proto][protocol];
193} 195}
194 196
197/* this is guaranteed to always return a valid protocol helper, since
198 * it falls back to generic_protocol */
199struct nf_conntrack_protocol *
200nf_ct_proto_find_get(u_int16_t l3proto, u_int8_t protocol)
201{
202 struct nf_conntrack_protocol *p;
203
204 preempt_disable();
205 p = __nf_ct_proto_find(l3proto, protocol);
206 if (p) {
207 if (!try_module_get(p->me))
208 p = &nf_conntrack_generic_protocol;
209 }
210 preempt_enable();
211
212 return p;
213}
214
215void nf_ct_proto_put(struct nf_conntrack_protocol *p)
216{
217 module_put(p->me);
218}
219
220struct nf_conntrack_l3proto *
221nf_ct_l3proto_find_get(u_int16_t l3proto)
222{
223 struct nf_conntrack_l3proto *p;
224
225 preempt_disable();
226 p = __nf_ct_l3proto_find(l3proto);
227 if (p) {
228 if (!try_module_get(p->me))
229 p = &nf_conntrack_generic_l3proto;
230 }
231 preempt_enable();
232
233 return p;
234}
235
236void nf_ct_l3proto_put(struct nf_conntrack_l3proto *p)
237{
238 module_put(p->me);
239}
240
195static int nf_conntrack_hash_rnd_initted; 241static int nf_conntrack_hash_rnd_initted;
196static unsigned int nf_conntrack_hash_rnd; 242static unsigned int nf_conntrack_hash_rnd;
197 243
@@ -384,7 +430,7 @@ nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse,
384} 430}
385 431
386/* nf_conntrack_expect helper functions */ 432/* nf_conntrack_expect helper functions */
387static void nf_ct_unlink_expect(struct nf_conntrack_expect *exp) 433void nf_ct_unlink_expect(struct nf_conntrack_expect *exp)
388{ 434{
389 ASSERT_WRITE_LOCK(&nf_conntrack_lock); 435 ASSERT_WRITE_LOCK(&nf_conntrack_lock);
390 NF_CT_ASSERT(!timer_pending(&exp->timeout)); 436 NF_CT_ASSERT(!timer_pending(&exp->timeout));
@@ -404,6 +450,33 @@ static void expectation_timed_out(unsigned long ul_expect)
404 nf_conntrack_expect_put(exp); 450 nf_conntrack_expect_put(exp);
405} 451}
406 452
453struct nf_conntrack_expect *
454__nf_conntrack_expect_find(const struct nf_conntrack_tuple *tuple)
455{
456 struct nf_conntrack_expect *i;
457
458 list_for_each_entry(i, &nf_conntrack_expect_list, list) {
459 if (nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask)) {
460 atomic_inc(&i->use);
461 return i;
462 }
463 }
464 return NULL;
465}
466
467/* Just find a expectation corresponding to a tuple. */
468struct nf_conntrack_expect *
469nf_conntrack_expect_find(const struct nf_conntrack_tuple *tuple)
470{
471 struct nf_conntrack_expect *i;
472
473 read_lock_bh(&nf_conntrack_lock);
474 i = __nf_conntrack_expect_find(tuple);
475 read_unlock_bh(&nf_conntrack_lock);
476
477 return i;
478}
479
407/* If an expectation for this connection is found, it gets delete from 480/* If an expectation for this connection is found, it gets delete from
408 * global list then returned. */ 481 * global list then returned. */
409static struct nf_conntrack_expect * 482static struct nf_conntrack_expect *
@@ -432,7 +505,7 @@ find_expectation(const struct nf_conntrack_tuple *tuple)
432} 505}
433 506
434/* delete all expectations for this conntrack */ 507/* delete all expectations for this conntrack */
435static void remove_expectations(struct nf_conn *ct) 508void nf_ct_remove_expectations(struct nf_conn *ct)
436{ 509{
437 struct nf_conntrack_expect *i, *tmp; 510 struct nf_conntrack_expect *i, *tmp;
438 511
@@ -462,7 +535,7 @@ clean_from_lists(struct nf_conn *ct)
462 LIST_DELETE(&nf_conntrack_hash[hr], &ct->tuplehash[IP_CT_DIR_REPLY]); 535 LIST_DELETE(&nf_conntrack_hash[hr], &ct->tuplehash[IP_CT_DIR_REPLY]);
463 536
464 /* Destroy all pending expectations */ 537 /* Destroy all pending expectations */
465 remove_expectations(ct); 538 nf_ct_remove_expectations(ct);
466} 539}
467 540
468static void 541static void
@@ -482,12 +555,11 @@ destroy_conntrack(struct nf_conntrack *nfct)
482 /* To make sure we don't get any weird locking issues here: 555 /* To make sure we don't get any weird locking issues here:
483 * destroy_conntrack() MUST NOT be called with a write lock 556 * destroy_conntrack() MUST NOT be called with a write lock
484 * to nf_conntrack_lock!!! -HW */ 557 * to nf_conntrack_lock!!! -HW */
485 l3proto = nf_ct_find_l3proto(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.l3num); 558 l3proto = __nf_ct_l3proto_find(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.l3num);
486 if (l3proto && l3proto->destroy) 559 if (l3proto && l3proto->destroy)
487 l3proto->destroy(ct); 560 l3proto->destroy(ct);
488 561
489 proto = nf_ct_find_proto(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.l3num, 562 proto = __nf_ct_proto_find(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.l3num, ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.protonum);
490 ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.protonum);
491 if (proto && proto->destroy) 563 if (proto && proto->destroy)
492 proto->destroy(ct); 564 proto->destroy(ct);
493 565
@@ -499,7 +571,7 @@ destroy_conntrack(struct nf_conntrack *nfct)
499 * except TFTP can create an expectation on the first packet, 571 * except TFTP can create an expectation on the first packet,
500 * before connection is in the list, so we need to clean here, 572 * before connection is in the list, so we need to clean here,
501 * too. */ 573 * too. */
502 remove_expectations(ct); 574 nf_ct_remove_expectations(ct);
503 575
504 /* We overload first tuple to link into unconfirmed list. */ 576 /* We overload first tuple to link into unconfirmed list. */
505 if (!nf_ct_is_confirmed(ct)) { 577 if (!nf_ct_is_confirmed(ct)) {
@@ -540,7 +612,7 @@ conntrack_tuple_cmp(const struct nf_conntrack_tuple_hash *i,
540 && nf_ct_tuple_equal(tuple, &i->tuple); 612 && nf_ct_tuple_equal(tuple, &i->tuple);
541} 613}
542 614
543static struct nf_conntrack_tuple_hash * 615struct nf_conntrack_tuple_hash *
544__nf_conntrack_find(const struct nf_conntrack_tuple *tuple, 616__nf_conntrack_find(const struct nf_conntrack_tuple *tuple,
545 const struct nf_conn *ignored_conntrack) 617 const struct nf_conn *ignored_conntrack)
546{ 618{
@@ -575,6 +647,29 @@ nf_conntrack_find_get(const struct nf_conntrack_tuple *tuple,
575 return h; 647 return h;
576} 648}
577 649
650static void __nf_conntrack_hash_insert(struct nf_conn *ct,
651 unsigned int hash,
652 unsigned int repl_hash)
653{
654 ct->id = ++nf_conntrack_next_id;
655 list_prepend(&nf_conntrack_hash[hash],
656 &ct->tuplehash[IP_CT_DIR_ORIGINAL].list);
657 list_prepend(&nf_conntrack_hash[repl_hash],
658 &ct->tuplehash[IP_CT_DIR_REPLY].list);
659}
660
661void nf_conntrack_hash_insert(struct nf_conn *ct)
662{
663 unsigned int hash, repl_hash;
664
665 hash = hash_conntrack(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
666 repl_hash = hash_conntrack(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
667
668 write_lock_bh(&nf_conntrack_lock);
669 __nf_conntrack_hash_insert(ct, hash, repl_hash);
670 write_unlock_bh(&nf_conntrack_lock);
671}
672
578/* Confirm a connection given skb; places it in hash table */ 673/* Confirm a connection given skb; places it in hash table */
579int 674int
580__nf_conntrack_confirm(struct sk_buff **pskb) 675__nf_conntrack_confirm(struct sk_buff **pskb)
@@ -621,10 +716,7 @@ __nf_conntrack_confirm(struct sk_buff **pskb)
621 /* Remove from unconfirmed list */ 716 /* Remove from unconfirmed list */
622 list_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list); 717 list_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list);
623 718
624 list_prepend(&nf_conntrack_hash[hash], 719 __nf_conntrack_hash_insert(ct, hash, repl_hash);
625 &ct->tuplehash[IP_CT_DIR_ORIGINAL]);
626 list_prepend(&nf_conntrack_hash[repl_hash],
627 &ct->tuplehash[IP_CT_DIR_REPLY]);
628 /* Timer relative to confirmation time, not original 720 /* Timer relative to confirmation time, not original
629 setting time, otherwise we'd get timer wrap in 721 setting time, otherwise we'd get timer wrap in
630 weird delay cases. */ 722 weird delay cases. */
@@ -708,13 +800,41 @@ static inline int helper_cmp(const struct nf_conntrack_helper *i,
708} 800}
709 801
710static struct nf_conntrack_helper * 802static struct nf_conntrack_helper *
711nf_ct_find_helper(const struct nf_conntrack_tuple *tuple) 803__nf_ct_helper_find(const struct nf_conntrack_tuple *tuple)
712{ 804{
713 return LIST_FIND(&helpers, helper_cmp, 805 return LIST_FIND(&helpers, helper_cmp,
714 struct nf_conntrack_helper *, 806 struct nf_conntrack_helper *,
715 tuple); 807 tuple);
716} 808}
717 809
810struct nf_conntrack_helper *
811nf_ct_helper_find_get( const struct nf_conntrack_tuple *tuple)
812{
813 struct nf_conntrack_helper *helper;
814
815 /* need nf_conntrack_lock to assure that helper exists until
816 * try_module_get() is called */
817 read_lock_bh(&nf_conntrack_lock);
818
819 helper = __nf_ct_helper_find(tuple);
820 if (helper) {
821 /* need to increase module usage count to assure helper will
822 * not go away while the caller is e.g. busy putting a
823 * conntrack in the hash that uses the helper */
824 if (!try_module_get(helper->me))
825 helper = NULL;
826 }
827
828 read_unlock_bh(&nf_conntrack_lock);
829
830 return helper;
831}
832
833void nf_ct_helper_put(struct nf_conntrack_helper *helper)
834{
835 module_put(helper->me);
836}
837
718static struct nf_conn * 838static struct nf_conn *
719__nf_conntrack_alloc(const struct nf_conntrack_tuple *orig, 839__nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
720 const struct nf_conntrack_tuple *repl, 840 const struct nf_conntrack_tuple *repl,
@@ -744,7 +864,7 @@ __nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
744 /* find features needed by this conntrack. */ 864 /* find features needed by this conntrack. */
745 features = l3proto->get_features(orig); 865 features = l3proto->get_features(orig);
746 read_lock_bh(&nf_conntrack_lock); 866 read_lock_bh(&nf_conntrack_lock);
747 if (nf_ct_find_helper(repl) != NULL) 867 if (__nf_ct_helper_find(repl) != NULL)
748 features |= NF_CT_F_HELP; 868 features |= NF_CT_F_HELP;
749 read_unlock_bh(&nf_conntrack_lock); 869 read_unlock_bh(&nf_conntrack_lock);
750 870
@@ -794,7 +914,7 @@ struct nf_conn *nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
794{ 914{
795 struct nf_conntrack_l3proto *l3proto; 915 struct nf_conntrack_l3proto *l3proto;
796 916
797 l3proto = nf_ct_find_l3proto(orig->src.l3num); 917 l3proto = __nf_ct_l3proto_find(orig->src.l3num);
798 return __nf_conntrack_alloc(orig, repl, l3proto); 918 return __nf_conntrack_alloc(orig, repl, l3proto);
799} 919}
800 920
@@ -853,7 +973,7 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
853 nf_conntrack_get(&conntrack->master->ct_general); 973 nf_conntrack_get(&conntrack->master->ct_general);
854 NF_CT_STAT_INC(expect_new); 974 NF_CT_STAT_INC(expect_new);
855 } else { 975 } else {
856 conntrack->helper = nf_ct_find_helper(&repl_tuple); 976 conntrack->helper = __nf_ct_helper_find(&repl_tuple);
857 977
858 NF_CT_STAT_INC(new); 978 NF_CT_STAT_INC(new);
859 } 979 }
@@ -947,13 +1067,13 @@ nf_conntrack_in(int pf, unsigned int hooknum, struct sk_buff **pskb)
947 return NF_ACCEPT; 1067 return NF_ACCEPT;
948 } 1068 }
949 1069
950 l3proto = nf_ct_find_l3proto((u_int16_t)pf); 1070 l3proto = __nf_ct_l3proto_find((u_int16_t)pf);
951 if ((ret = l3proto->prepare(pskb, hooknum, &dataoff, &protonum)) <= 0) { 1071 if ((ret = l3proto->prepare(pskb, hooknum, &dataoff, &protonum)) <= 0) {
952 DEBUGP("not prepared to track yet or error occured\n"); 1072 DEBUGP("not prepared to track yet or error occured\n");
953 return -ret; 1073 return -ret;
954 } 1074 }
955 1075
956 proto = nf_ct_find_proto((u_int16_t)pf, protonum); 1076 proto = __nf_ct_proto_find((u_int16_t)pf, protonum);
957 1077
958 /* It may be an special packet, error, unclean... 1078 /* It may be an special packet, error, unclean...
959 * inverse of the return code tells to the netfilter 1079 * inverse of the return code tells to the netfilter
@@ -1002,9 +1122,9 @@ int nf_ct_invert_tuplepr(struct nf_conntrack_tuple *inverse,
1002 const struct nf_conntrack_tuple *orig) 1122 const struct nf_conntrack_tuple *orig)
1003{ 1123{
1004 return nf_ct_invert_tuple(inverse, orig, 1124 return nf_ct_invert_tuple(inverse, orig,
1005 nf_ct_find_l3proto(orig->src.l3num), 1125 __nf_ct_l3proto_find(orig->src.l3num),
1006 nf_ct_find_proto(orig->src.l3num, 1126 __nf_ct_proto_find(orig->src.l3num,
1007 orig->dst.protonum)); 1127 orig->dst.protonum));
1008} 1128}
1009 1129
1010/* Would two expected things clash? */ 1130/* Would two expected things clash? */
@@ -1096,6 +1216,7 @@ static void nf_conntrack_expect_insert(struct nf_conntrack_expect *exp)
1096 exp->timeout.expires = jiffies + exp->master->helper->timeout * HZ; 1216 exp->timeout.expires = jiffies + exp->master->helper->timeout * HZ;
1097 add_timer(&exp->timeout); 1217 add_timer(&exp->timeout);
1098 1218
1219 exp->id = ++nf_conntrack_expect_next_id;
1099 atomic_inc(&exp->use); 1220 atomic_inc(&exp->use);
1100 NF_CT_STAT_INC(expect_create); 1221 NF_CT_STAT_INC(expect_create);
1101} 1222}
@@ -1129,6 +1250,7 @@ static inline int refresh_timer(struct nf_conntrack_expect *i)
1129int nf_conntrack_expect_related(struct nf_conntrack_expect *expect) 1250int nf_conntrack_expect_related(struct nf_conntrack_expect *expect)
1130{ 1251{
1131 struct nf_conntrack_expect *i; 1252 struct nf_conntrack_expect *i;
1253 struct nf_conn *master = expect->master;
1132 int ret; 1254 int ret;
1133 1255
1134 DEBUGP("nf_conntrack_expect_related %p\n", related_to); 1256 DEBUGP("nf_conntrack_expect_related %p\n", related_to);
@@ -1149,9 +1271,9 @@ int nf_conntrack_expect_related(struct nf_conntrack_expect *expect)
1149 } 1271 }
1150 } 1272 }
1151 /* Will be over limit? */ 1273 /* Will be over limit? */
1152 if (expect->master->helper->max_expected && 1274 if (master->helper->max_expected &&
1153 expect->master->expecting >= expect->master->helper->max_expected) 1275 master->expecting >= master->helper->max_expected)
1154 evict_oldest_expect(expect->master); 1276 evict_oldest_expect(master);
1155 1277
1156 nf_conntrack_expect_insert(expect); 1278 nf_conntrack_expect_insert(expect);
1157 nf_conntrack_expect_event(IPEXP_NEW, expect); 1279 nf_conntrack_expect_event(IPEXP_NEW, expect);
@@ -1175,7 +1297,7 @@ void nf_conntrack_alter_reply(struct nf_conn *conntrack,
1175 1297
1176 conntrack->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply; 1298 conntrack->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply;
1177 if (!conntrack->master && conntrack->expecting == 0) 1299 if (!conntrack->master && conntrack->expecting == 0)
1178 conntrack->helper = nf_ct_find_helper(newreply); 1300 conntrack->helper = __nf_ct_helper_find(newreply);
1179 write_unlock_bh(&nf_conntrack_lock); 1301 write_unlock_bh(&nf_conntrack_lock);
1180} 1302}
1181 1303
@@ -1200,6 +1322,19 @@ int nf_conntrack_helper_register(struct nf_conntrack_helper *me)
1200 return 0; 1322 return 0;
1201} 1323}
1202 1324
1325struct nf_conntrack_helper *
1326__nf_conntrack_helper_find_byname(const char *name)
1327{
1328 struct nf_conntrack_helper *h;
1329
1330 list_for_each_entry(h, &helpers, list) {
1331 if (!strcmp(h->name, name))
1332 return h;
1333 }
1334
1335 return NULL;
1336}
1337
1203static inline int unhelp(struct nf_conntrack_tuple_hash *i, 1338static inline int unhelp(struct nf_conntrack_tuple_hash *i,
1204 const struct nf_conntrack_helper *me) 1339 const struct nf_conntrack_helper *me)
1205{ 1340{
@@ -1283,6 +1418,51 @@ void __nf_ct_refresh_acct(struct nf_conn *ct,
1283 nf_conntrack_event_cache(event, skb); 1418 nf_conntrack_event_cache(event, skb);
1284} 1419}
1285 1420
1421#if defined(CONFIG_NF_CT_NETLINK) || \
1422 defined(CONFIG_NF_CT_NETLINK_MODULE)
1423
1424#include <linux/netfilter/nfnetlink.h>
1425#include <linux/netfilter/nfnetlink_conntrack.h>
1426
1427/* Generic function for tcp/udp/sctp/dccp and alike. This needs to be
1428 * in ip_conntrack_core, since we don't want the protocols to autoload
1429 * or depend on ctnetlink */
1430int nf_ct_port_tuple_to_nfattr(struct sk_buff *skb,
1431 const struct nf_conntrack_tuple *tuple)
1432{
1433 NFA_PUT(skb, CTA_PROTO_SRC_PORT, sizeof(u_int16_t),
1434 &tuple->src.u.tcp.port);
1435 NFA_PUT(skb, CTA_PROTO_DST_PORT, sizeof(u_int16_t),
1436 &tuple->dst.u.tcp.port);
1437 return 0;
1438
1439nfattr_failure:
1440 return -1;
1441}
1442
1443static const size_t cta_min_proto[CTA_PROTO_MAX] = {
1444 [CTA_PROTO_SRC_PORT-1] = sizeof(u_int16_t),
1445 [CTA_PROTO_DST_PORT-1] = sizeof(u_int16_t)
1446};
1447
1448int nf_ct_port_nfattr_to_tuple(struct nfattr *tb[],
1449 struct nf_conntrack_tuple *t)
1450{
1451 if (!tb[CTA_PROTO_SRC_PORT-1] || !tb[CTA_PROTO_DST_PORT-1])
1452 return -EINVAL;
1453
1454 if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto))
1455 return -EINVAL;
1456
1457 t->src.u.tcp.port =
1458 *(u_int16_t *)NFA_DATA(tb[CTA_PROTO_SRC_PORT-1]);
1459 t->dst.u.tcp.port =
1460 *(u_int16_t *)NFA_DATA(tb[CTA_PROTO_DST_PORT-1]);
1461
1462 return 0;
1463}
1464#endif
1465
1286/* Used by ipt_REJECT and ip6t_REJECT. */ 1466/* Used by ipt_REJECT and ip6t_REJECT. */
1287void __nf_conntrack_attach(struct sk_buff *nskb, struct sk_buff *skb) 1467void __nf_conntrack_attach(struct sk_buff *nskb, struct sk_buff *skb)
1288{ 1468{
@@ -1365,6 +1545,11 @@ static void free_conntrack_hash(struct list_head *hash, int vmalloced, int size)
1365 get_order(sizeof(struct list_head) * size)); 1545 get_order(sizeof(struct list_head) * size));
1366} 1546}
1367 1547
1548void nf_conntrack_flush()
1549{
1550 nf_ct_iterate_cleanup(kill_all, NULL);
1551}
1552
1368/* Mishearing the voices in his head, our hero wonders how he's 1553/* Mishearing the voices in his head, our hero wonders how he's
1369 supposed to kill the mall. */ 1554 supposed to kill the mall. */
1370void nf_conntrack_cleanup(void) 1555void nf_conntrack_cleanup(void)
@@ -1378,7 +1563,7 @@ void nf_conntrack_cleanup(void)
1378 1563
1379 nf_ct_event_cache_flush(); 1564 nf_ct_event_cache_flush();
1380 i_see_dead_people: 1565 i_see_dead_people:
1381 nf_ct_iterate_cleanup(kill_all, NULL); 1566 nf_conntrack_flush();
1382 if (atomic_read(&nf_conntrack_count) != 0) { 1567 if (atomic_read(&nf_conntrack_count) != 0) {
1383 schedule(); 1568 schedule();
1384 goto i_see_dead_people; 1569 goto i_see_dead_people;
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c
index 65080e269f27..d5a6eaf4a1de 100644
--- a/net/netfilter/nf_conntrack_ftp.c
+++ b/net/netfilter/nf_conntrack_ftp.c
@@ -44,7 +44,7 @@ static unsigned int ports_c;
44module_param_array(ports, ushort, &ports_c, 0400); 44module_param_array(ports, ushort, &ports_c, 0400);
45 45
46static int loose; 46static int loose;
47module_param(loose, int, 0600); 47module_param(loose, bool, 0600);
48 48
49unsigned int (*nf_nat_ftp_hook)(struct sk_buff **pskb, 49unsigned int (*nf_nat_ftp_hook)(struct sk_buff **pskb,
50 enum ip_conntrack_info ctinfo, 50 enum ip_conntrack_info ctinfo,
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
new file mode 100644
index 000000000000..73ab16bc7d40
--- /dev/null
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -0,0 +1,1653 @@
1/* Connection tracking via netlink socket. Allows for user space
2 * protocol helpers and general trouble making from userspace.
3 *
4 * (C) 2001 by Jay Schulist <jschlst@samba.org>
5 * (C) 2002-2005 by Harald Welte <laforge@gnumonks.org>
6 * (C) 2003 by Patrick Mchardy <kaber@trash.net>
7 * (C) 2005 by Pablo Neira Ayuso <pablo@eurodev.net>
8 *
9 * I've reworked this stuff to use attributes instead of conntrack
10 * structures. 5.44 am. I need more tea. --pablo 05/07/11.
11 *
12 * Initial connection tracking via netlink development funded and
13 * generally made possible by Network Robots, Inc. (www.networkrobots.com)
14 *
15 * Further development of this code funded by Astaro AG (http://www.astaro.com)
16 *
17 * This software may be used and distributed according to the terms
18 * of the GNU General Public License, incorporated herein by reference.
19 *
20 * Derived from ip_conntrack_netlink.c: Port by Pablo Neira Ayuso (05/11/14)
21 */
22
23#include <linux/init.h>
24#include <linux/module.h>
25#include <linux/kernel.h>
26#include <linux/types.h>
27#include <linux/timer.h>
28#include <linux/skbuff.h>
29#include <linux/errno.h>
30#include <linux/netlink.h>
31#include <linux/spinlock.h>
32#include <linux/notifier.h>
33
34#include <linux/netfilter.h>
35#include <net/netfilter/nf_conntrack.h>
36#include <net/netfilter/nf_conntrack_core.h>
37#include <net/netfilter/nf_conntrack_helper.h>
38#include <net/netfilter/nf_conntrack_l3proto.h>
39#include <net/netfilter/nf_conntrack_protocol.h>
40#include <linux/netfilter_ipv4/ip_nat_protocol.h>
41
42#include <linux/netfilter/nfnetlink.h>
43#include <linux/netfilter/nfnetlink_conntrack.h>
44
45MODULE_LICENSE("GPL");
46
47static char __initdata version[] = "0.92";
48
49#if 0
50#define DEBUGP printk
51#else
52#define DEBUGP(format, args...)
53#endif
54
55
56static inline int
57ctnetlink_dump_tuples_proto(struct sk_buff *skb,
58 const struct nf_conntrack_tuple *tuple)
59{
60 struct nf_conntrack_protocol *proto;
61 int ret = 0;
62
63 NFA_PUT(skb, CTA_PROTO_NUM, sizeof(u_int8_t), &tuple->dst.protonum);
64
65 /* If no protocol helper is found, this function will return the
66 * generic protocol helper, so proto won't *ever* be NULL */
67 proto = nf_ct_proto_find_get(tuple->src.l3num, tuple->dst.protonum);
68 if (likely(proto->tuple_to_nfattr))
69 ret = proto->tuple_to_nfattr(skb, tuple);
70
71 nf_ct_proto_put(proto);
72
73 return ret;
74
75nfattr_failure:
76 return -1;
77}
78
79static inline int
80ctnetlink_dump_tuples(struct sk_buff *skb,
81 const struct nf_conntrack_tuple *tuple)
82{
83 struct nfattr *nest_parms;
84 struct nf_conntrack_l3proto *l3proto;
85 int ret = 0;
86
87 l3proto = nf_ct_l3proto_find_get(tuple->src.l3num);
88
89 nest_parms = NFA_NEST(skb, CTA_TUPLE_IP);
90 if (likely(l3proto->tuple_to_nfattr))
91 ret = l3proto->tuple_to_nfattr(skb, tuple);
92 NFA_NEST_END(skb, nest_parms);
93
94 nf_ct_l3proto_put(l3proto);
95
96 if (unlikely(ret < 0))
97 return ret;
98
99 nest_parms = NFA_NEST(skb, CTA_TUPLE_PROTO);
100 ret = ctnetlink_dump_tuples_proto(skb, tuple);
101 NFA_NEST_END(skb, nest_parms);
102
103 return ret;
104
105nfattr_failure:
106 return -1;
107}
108
109static inline int
110ctnetlink_dump_status(struct sk_buff *skb, const struct nf_conn *ct)
111{
112 u_int32_t status = htonl((u_int32_t) ct->status);
113 NFA_PUT(skb, CTA_STATUS, sizeof(status), &status);
114 return 0;
115
116nfattr_failure:
117 return -1;
118}
119
120static inline int
121ctnetlink_dump_timeout(struct sk_buff *skb, const struct nf_conn *ct)
122{
123 long timeout_l = ct->timeout.expires - jiffies;
124 u_int32_t timeout;
125
126 if (timeout_l < 0)
127 timeout = 0;
128 else
129 timeout = htonl(timeout_l / HZ);
130
131 NFA_PUT(skb, CTA_TIMEOUT, sizeof(timeout), &timeout);
132 return 0;
133
134nfattr_failure:
135 return -1;
136}
137
138static inline int
139ctnetlink_dump_protoinfo(struct sk_buff *skb, const struct nf_conn *ct)
140{
141 struct nf_conntrack_protocol *proto = nf_ct_proto_find_get(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num, ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum);
142 struct nfattr *nest_proto;
143 int ret;
144
145 if (!proto->to_nfattr) {
146 nf_ct_proto_put(proto);
147 return 0;
148 }
149
150 nest_proto = NFA_NEST(skb, CTA_PROTOINFO);
151
152 ret = proto->to_nfattr(skb, nest_proto, ct);
153
154 nf_ct_proto_put(proto);
155
156 NFA_NEST_END(skb, nest_proto);
157
158 return ret;
159
160nfattr_failure:
161 return -1;
162}
163
164static inline int
165ctnetlink_dump_helpinfo(struct sk_buff *skb, const struct nf_conn *ct)
166{
167 struct nfattr *nest_helper;
168
169 if (!ct->helper)
170 return 0;
171
172 nest_helper = NFA_NEST(skb, CTA_HELP);
173 NFA_PUT(skb, CTA_HELP_NAME, strlen(ct->helper->name), ct->helper->name);
174
175 if (ct->helper->to_nfattr)
176 ct->helper->to_nfattr(skb, ct);
177
178 NFA_NEST_END(skb, nest_helper);
179
180 return 0;
181
182nfattr_failure:
183 return -1;
184}
185
186#ifdef CONFIG_NF_CT_ACCT
187static inline int
188ctnetlink_dump_counters(struct sk_buff *skb, const struct nf_conn *ct,
189 enum ip_conntrack_dir dir)
190{
191 enum ctattr_type type = dir ? CTA_COUNTERS_REPLY: CTA_COUNTERS_ORIG;
192 struct nfattr *nest_count = NFA_NEST(skb, type);
193 u_int32_t tmp;
194
195 tmp = htonl(ct->counters[dir].packets);
196 NFA_PUT(skb, CTA_COUNTERS32_PACKETS, sizeof(u_int32_t), &tmp);
197
198 tmp = htonl(ct->counters[dir].bytes);
199 NFA_PUT(skb, CTA_COUNTERS32_BYTES, sizeof(u_int32_t), &tmp);
200
201 NFA_NEST_END(skb, nest_count);
202
203 return 0;
204
205nfattr_failure:
206 return -1;
207}
208#else
209#define ctnetlink_dump_counters(a, b, c) (0)
210#endif
211
212#ifdef CONFIG_NF_CONNTRACK_MARK
213static inline int
214ctnetlink_dump_mark(struct sk_buff *skb, const struct nf_conn *ct)
215{
216 u_int32_t mark = htonl(ct->mark);
217
218 NFA_PUT(skb, CTA_MARK, sizeof(u_int32_t), &mark);
219 return 0;
220
221nfattr_failure:
222 return -1;
223}
224#else
225#define ctnetlink_dump_mark(a, b) (0)
226#endif
227
228static inline int
229ctnetlink_dump_id(struct sk_buff *skb, const struct nf_conn *ct)
230{
231 u_int32_t id = htonl(ct->id);
232 NFA_PUT(skb, CTA_ID, sizeof(u_int32_t), &id);
233 return 0;
234
235nfattr_failure:
236 return -1;
237}
238
239static inline int
240ctnetlink_dump_use(struct sk_buff *skb, const struct nf_conn *ct)
241{
242 u_int32_t use = htonl(atomic_read(&ct->ct_general.use));
243
244 NFA_PUT(skb, CTA_USE, sizeof(u_int32_t), &use);
245 return 0;
246
247nfattr_failure:
248 return -1;
249}
250
251#define tuple(ct, dir) (&(ct)->tuplehash[dir].tuple)
252
253static int
254ctnetlink_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
255 int event, int nowait,
256 const struct nf_conn *ct)
257{
258 struct nlmsghdr *nlh;
259 struct nfgenmsg *nfmsg;
260 struct nfattr *nest_parms;
261 unsigned char *b;
262
263 b = skb->tail;
264
265 event |= NFNL_SUBSYS_CTNETLINK << 8;
266 nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(struct nfgenmsg));
267 nfmsg = NLMSG_DATA(nlh);
268
269 nlh->nlmsg_flags = (nowait && pid) ? NLM_F_MULTI : 0;
270 nfmsg->nfgen_family =
271 ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
272 nfmsg->version = NFNETLINK_V0;
273 nfmsg->res_id = 0;
274
275 nest_parms = NFA_NEST(skb, CTA_TUPLE_ORIG);
276 if (ctnetlink_dump_tuples(skb, tuple(ct, IP_CT_DIR_ORIGINAL)) < 0)
277 goto nfattr_failure;
278 NFA_NEST_END(skb, nest_parms);
279
280 nest_parms = NFA_NEST(skb, CTA_TUPLE_REPLY);
281 if (ctnetlink_dump_tuples(skb, tuple(ct, IP_CT_DIR_REPLY)) < 0)
282 goto nfattr_failure;
283 NFA_NEST_END(skb, nest_parms);
284
285 if (ctnetlink_dump_status(skb, ct) < 0 ||
286 ctnetlink_dump_timeout(skb, ct) < 0 ||
287 ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL) < 0 ||
288 ctnetlink_dump_counters(skb, ct, IP_CT_DIR_REPLY) < 0 ||
289 ctnetlink_dump_protoinfo(skb, ct) < 0 ||
290 ctnetlink_dump_helpinfo(skb, ct) < 0 ||
291 ctnetlink_dump_mark(skb, ct) < 0 ||
292 ctnetlink_dump_id(skb, ct) < 0 ||
293 ctnetlink_dump_use(skb, ct) < 0)
294 goto nfattr_failure;
295
296 nlh->nlmsg_len = skb->tail - b;
297 return skb->len;
298
299nlmsg_failure:
300nfattr_failure:
301 skb_trim(skb, b - skb->data);
302 return -1;
303}
304
305#ifdef CONFIG_NF_CONNTRACK_EVENTS
306static int ctnetlink_conntrack_event(struct notifier_block *this,
307 unsigned long events, void *ptr)
308{
309 struct nlmsghdr *nlh;
310 struct nfgenmsg *nfmsg;
311 struct nfattr *nest_parms;
312 struct nf_conn *ct = (struct nf_conn *)ptr;
313 struct sk_buff *skb;
314 unsigned int type;
315 unsigned char *b;
316 unsigned int flags = 0, group;
317
318 /* ignore our fake conntrack entry */
319 if (ct == &nf_conntrack_untracked)
320 return NOTIFY_DONE;
321
322 if (events & IPCT_DESTROY) {
323 type = IPCTNL_MSG_CT_DELETE;
324 group = NFNLGRP_CONNTRACK_DESTROY;
325 } else if (events & (IPCT_NEW | IPCT_RELATED)) {
326 type = IPCTNL_MSG_CT_NEW;
327 flags = NLM_F_CREATE|NLM_F_EXCL;
328 /* dump everything */
329 events = ~0UL;
330 group = NFNLGRP_CONNTRACK_NEW;
331 } else if (events & (IPCT_STATUS |
332 IPCT_PROTOINFO |
333 IPCT_HELPER |
334 IPCT_HELPINFO |
335 IPCT_NATINFO)) {
336 type = IPCTNL_MSG_CT_NEW;
337 group = NFNLGRP_CONNTRACK_UPDATE;
338 } else
339 return NOTIFY_DONE;
340
341 /* FIXME: Check if there are any listeners before, don't hurt performance */
342
343 skb = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC);
344 if (!skb)
345 return NOTIFY_DONE;
346
347 b = skb->tail;
348
349 type |= NFNL_SUBSYS_CTNETLINK << 8;
350 nlh = NLMSG_PUT(skb, 0, 0, type, sizeof(struct nfgenmsg));
351 nfmsg = NLMSG_DATA(nlh);
352
353 nlh->nlmsg_flags = flags;
354 nfmsg->nfgen_family = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
355 nfmsg->version = NFNETLINK_V0;
356 nfmsg->res_id = 0;
357
358 nest_parms = NFA_NEST(skb, CTA_TUPLE_ORIG);
359 if (ctnetlink_dump_tuples(skb, tuple(ct, IP_CT_DIR_ORIGINAL)) < 0)
360 goto nfattr_failure;
361 NFA_NEST_END(skb, nest_parms);
362
363 nest_parms = NFA_NEST(skb, CTA_TUPLE_REPLY);
364 if (ctnetlink_dump_tuples(skb, tuple(ct, IP_CT_DIR_REPLY)) < 0)
365 goto nfattr_failure;
366 NFA_NEST_END(skb, nest_parms);
367
368 /* NAT stuff is now a status flag */
369 if ((events & IPCT_STATUS || events & IPCT_NATINFO)
370 && ctnetlink_dump_status(skb, ct) < 0)
371 goto nfattr_failure;
372 if (events & IPCT_REFRESH
373 && ctnetlink_dump_timeout(skb, ct) < 0)
374 goto nfattr_failure;
375 if (events & IPCT_PROTOINFO
376 && ctnetlink_dump_protoinfo(skb, ct) < 0)
377 goto nfattr_failure;
378 if (events & IPCT_HELPINFO
379 && ctnetlink_dump_helpinfo(skb, ct) < 0)
380 goto nfattr_failure;
381
382 if (ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL) < 0 ||
383 ctnetlink_dump_counters(skb, ct, IP_CT_DIR_REPLY) < 0)
384 goto nfattr_failure;
385
386 nlh->nlmsg_len = skb->tail - b;
387 nfnetlink_send(skb, 0, group, 0);
388 return NOTIFY_DONE;
389
390nlmsg_failure:
391nfattr_failure:
392 kfree_skb(skb);
393 return NOTIFY_DONE;
394}
395#endif /* CONFIG_NF_CONNTRACK_EVENTS */
396
397static int ctnetlink_done(struct netlink_callback *cb)
398{
399 DEBUGP("entered %s\n", __FUNCTION__);
400 return 0;
401}
402
403#define L3PROTO(ct) ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num
404
405static int
406ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
407{
408 struct nf_conn *ct = NULL;
409 struct nf_conntrack_tuple_hash *h;
410 struct list_head *i;
411 u_int32_t *id = (u_int32_t *) &cb->args[1];
412 struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh);
413 u_int8_t l3proto = nfmsg->nfgen_family;
414
415 DEBUGP("entered %s, last bucket=%lu id=%u\n", __FUNCTION__,
416 cb->args[0], *id);
417
418 read_lock_bh(&nf_conntrack_lock);
419 for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++, *id = 0) {
420 list_for_each_prev(i, &nf_conntrack_hash[cb->args[0]]) {
421 h = (struct nf_conntrack_tuple_hash *) i;
422 if (DIRECTION(h) != IP_CT_DIR_ORIGINAL)
423 continue;
424 ct = nf_ct_tuplehash_to_ctrack(h);
425 /* Dump entries of a given L3 protocol number.
426 * If it is not specified, ie. l3proto == 0,
427 * then dump everything. */
428 if (l3proto && L3PROTO(ct) != l3proto)
429 continue;
430 if (ct->id <= *id)
431 continue;
432 if (ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).pid,
433 cb->nlh->nlmsg_seq,
434 IPCTNL_MSG_CT_NEW,
435 1, ct) < 0)
436 goto out;
437 *id = ct->id;
438 }
439 }
440out:
441 read_unlock_bh(&nf_conntrack_lock);
442
443 DEBUGP("leaving, last bucket=%lu id=%u\n", cb->args[0], *id);
444
445 return skb->len;
446}
447
448#ifdef CONFIG_NF_CT_ACCT
449static int
450ctnetlink_dump_table_w(struct sk_buff *skb, struct netlink_callback *cb)
451{
452 struct nf_conn *ct = NULL;
453 struct nf_conntrack_tuple_hash *h;
454 struct list_head *i;
455 u_int32_t *id = (u_int32_t *) &cb->args[1];
456 struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh);
457 u_int8_t l3proto = nfmsg->nfgen_family;
458
459 DEBUGP("entered %s, last bucket=%u id=%u\n", __FUNCTION__,
460 cb->args[0], *id);
461
462 write_lock_bh(&nf_conntrack_lock);
463 for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++, *id = 0) {
464 list_for_each_prev(i, &nf_conntrack_hash[cb->args[0]]) {
465 h = (struct nf_conntrack_tuple_hash *) i;
466 if (DIRECTION(h) != IP_CT_DIR_ORIGINAL)
467 continue;
468 ct = nf_ct_tuplehash_to_ctrack(h);
469 if (l3proto && L3PROTO(ct) != l3proto)
470 continue;
471 if (ct->id <= *id)
472 continue;
473 if (ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).pid,
474 cb->nlh->nlmsg_seq,
475 IPCTNL_MSG_CT_NEW,
476 1, ct) < 0)
477 goto out;
478 *id = ct->id;
479
480 memset(&ct->counters, 0, sizeof(ct->counters));
481 }
482 }
483out:
484 write_unlock_bh(&nf_conntrack_lock);
485
486 DEBUGP("leaving, last bucket=%lu id=%u\n", cb->args[0], *id);
487
488 return skb->len;
489}
490#endif
491
492static inline int
493ctnetlink_parse_tuple_ip(struct nfattr *attr, struct nf_conntrack_tuple *tuple)
494{
495 struct nfattr *tb[CTA_IP_MAX];
496 struct nf_conntrack_l3proto *l3proto;
497 int ret = 0;
498
499 DEBUGP("entered %s\n", __FUNCTION__);
500
501 nfattr_parse_nested(tb, CTA_IP_MAX, attr);
502
503 l3proto = nf_ct_l3proto_find_get(tuple->src.l3num);
504
505 if (likely(l3proto->nfattr_to_tuple))
506 ret = l3proto->nfattr_to_tuple(tb, tuple);
507
508 nf_ct_l3proto_put(l3proto);
509
510 DEBUGP("leaving\n");
511
512 return ret;
513}
514
515static const size_t cta_min_proto[CTA_PROTO_MAX] = {
516 [CTA_PROTO_NUM-1] = sizeof(u_int8_t),
517};
518
519static inline int
520ctnetlink_parse_tuple_proto(struct nfattr *attr,
521 struct nf_conntrack_tuple *tuple)
522{
523 struct nfattr *tb[CTA_PROTO_MAX];
524 struct nf_conntrack_protocol *proto;
525 int ret = 0;
526
527 DEBUGP("entered %s\n", __FUNCTION__);
528
529 nfattr_parse_nested(tb, CTA_PROTO_MAX, attr);
530
531 if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto))
532 return -EINVAL;
533
534 if (!tb[CTA_PROTO_NUM-1])
535 return -EINVAL;
536 tuple->dst.protonum = *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_NUM-1]);
537
538 proto = nf_ct_proto_find_get(tuple->src.l3num, tuple->dst.protonum);
539
540 if (likely(proto->nfattr_to_tuple))
541 ret = proto->nfattr_to_tuple(tb, tuple);
542
543 nf_ct_proto_put(proto);
544
545 return ret;
546}
547
548static inline int
549ctnetlink_parse_tuple(struct nfattr *cda[], struct nf_conntrack_tuple *tuple,
550 enum ctattr_tuple type, u_int8_t l3num)
551{
552 struct nfattr *tb[CTA_TUPLE_MAX];
553 int err;
554
555 DEBUGP("entered %s\n", __FUNCTION__);
556
557 memset(tuple, 0, sizeof(*tuple));
558
559 nfattr_parse_nested(tb, CTA_TUPLE_MAX, cda[type-1]);
560
561 if (!tb[CTA_TUPLE_IP-1])
562 return -EINVAL;
563
564 tuple->src.l3num = l3num;
565
566 err = ctnetlink_parse_tuple_ip(tb[CTA_TUPLE_IP-1], tuple);
567 if (err < 0)
568 return err;
569
570 if (!tb[CTA_TUPLE_PROTO-1])
571 return -EINVAL;
572
573 err = ctnetlink_parse_tuple_proto(tb[CTA_TUPLE_PROTO-1], tuple);
574 if (err < 0)
575 return err;
576
577 /* orig and expect tuples get DIR_ORIGINAL */
578 if (type == CTA_TUPLE_REPLY)
579 tuple->dst.dir = IP_CT_DIR_REPLY;
580 else
581 tuple->dst.dir = IP_CT_DIR_ORIGINAL;
582
583 NF_CT_DUMP_TUPLE(tuple);
584
585 DEBUGP("leaving\n");
586
587 return 0;
588}
589
590#ifdef CONFIG_IP_NF_NAT_NEEDED
591static const size_t cta_min_protonat[CTA_PROTONAT_MAX] = {
592 [CTA_PROTONAT_PORT_MIN-1] = sizeof(u_int16_t),
593 [CTA_PROTONAT_PORT_MAX-1] = sizeof(u_int16_t),
594};
595
596static int ctnetlink_parse_nat_proto(struct nfattr *attr,
597 const struct nf_conn *ct,
598 struct ip_nat_range *range)
599{
600 struct nfattr *tb[CTA_PROTONAT_MAX];
601 struct ip_nat_protocol *npt;
602
603 DEBUGP("entered %s\n", __FUNCTION__);
604
605 nfattr_parse_nested(tb, CTA_PROTONAT_MAX, attr);
606
607 if (nfattr_bad_size(tb, CTA_PROTONAT_MAX, cta_min_protonat))
608 return -EINVAL;
609
610 npt = ip_nat_proto_find_get(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum);
611
612 if (!npt->nfattr_to_range) {
613 ip_nat_proto_put(npt);
614 return 0;
615 }
616
617 /* nfattr_to_range returns 1 if it parsed, 0 if not, neg. on error */
618 if (npt->nfattr_to_range(tb, range) > 0)
619 range->flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
620
621 ip_nat_proto_put(npt);
622
623 DEBUGP("leaving\n");
624 return 0;
625}
626
627static const size_t cta_min_nat[CTA_NAT_MAX] = {
628 [CTA_NAT_MINIP-1] = sizeof(u_int32_t),
629 [CTA_NAT_MAXIP-1] = sizeof(u_int32_t),
630};
631
632static inline int
633ctnetlink_parse_nat(struct nfattr *cda[],
634 const struct nf_conn *ct, struct ip_nat_range *range)
635{
636 struct nfattr *tb[CTA_NAT_MAX];
637 int err;
638
639 DEBUGP("entered %s\n", __FUNCTION__);
640
641 memset(range, 0, sizeof(*range));
642
643 nfattr_parse_nested(tb, CTA_NAT_MAX, cda[CTA_NAT-1]);
644
645 if (nfattr_bad_size(tb, CTA_NAT_MAX, cta_min_nat))
646 return -EINVAL;
647
648 if (tb[CTA_NAT_MINIP-1])
649 range->min_ip = *(u_int32_t *)NFA_DATA(tb[CTA_NAT_MINIP-1]);
650
651 if (!tb[CTA_NAT_MAXIP-1])
652 range->max_ip = range->min_ip;
653 else
654 range->max_ip = *(u_int32_t *)NFA_DATA(tb[CTA_NAT_MAXIP-1]);
655
656 if (range->min_ip)
657 range->flags |= IP_NAT_RANGE_MAP_IPS;
658
659 if (!tb[CTA_NAT_PROTO-1])
660 return 0;
661
662 err = ctnetlink_parse_nat_proto(tb[CTA_NAT_PROTO-1], ct, range);
663 if (err < 0)
664 return err;
665
666 DEBUGP("leaving\n");
667 return 0;
668}
669#endif
670
671static inline int
672ctnetlink_parse_help(struct nfattr *attr, char **helper_name)
673{
674 struct nfattr *tb[CTA_HELP_MAX];
675
676 DEBUGP("entered %s\n", __FUNCTION__);
677
678 nfattr_parse_nested(tb, CTA_HELP_MAX, attr);
679
680 if (!tb[CTA_HELP_NAME-1])
681 return -EINVAL;
682
683 *helper_name = NFA_DATA(tb[CTA_HELP_NAME-1]);
684
685 return 0;
686}
687
688static const size_t cta_min[CTA_MAX] = {
689 [CTA_STATUS-1] = sizeof(u_int32_t),
690 [CTA_TIMEOUT-1] = sizeof(u_int32_t),
691 [CTA_MARK-1] = sizeof(u_int32_t),
692 [CTA_USE-1] = sizeof(u_int32_t),
693 [CTA_ID-1] = sizeof(u_int32_t)
694};
695
696static int
697ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
698 struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
699{
700 struct nf_conntrack_tuple_hash *h;
701 struct nf_conntrack_tuple tuple;
702 struct nf_conn *ct;
703 struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
704 u_int8_t u3 = nfmsg->nfgen_family;
705 int err = 0;
706
707 DEBUGP("entered %s\n", __FUNCTION__);
708
709 if (nfattr_bad_size(cda, CTA_MAX, cta_min))
710 return -EINVAL;
711
712 if (cda[CTA_TUPLE_ORIG-1])
713 err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG, u3);
714 else if (cda[CTA_TUPLE_REPLY-1])
715 err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY, u3);
716 else {
717 /* Flush the whole table */
718 nf_conntrack_flush();
719 return 0;
720 }
721
722 if (err < 0)
723 return err;
724
725 h = nf_conntrack_find_get(&tuple, NULL);
726 if (!h) {
727 DEBUGP("tuple not found in conntrack hash\n");
728 return -ENOENT;
729 }
730
731 ct = nf_ct_tuplehash_to_ctrack(h);
732
733 if (cda[CTA_ID-1]) {
734 u_int32_t id = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_ID-1]));
735 if (ct->id != id) {
736 nf_ct_put(ct);
737 return -ENOENT;
738 }
739 }
740 if (del_timer(&ct->timeout))
741 ct->timeout.function((unsigned long)ct);
742
743 nf_ct_put(ct);
744 DEBUGP("leaving\n");
745
746 return 0;
747}
748
749static int
750ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
751 struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
752{
753 struct nf_conntrack_tuple_hash *h;
754 struct nf_conntrack_tuple tuple;
755 struct nf_conn *ct;
756 struct sk_buff *skb2 = NULL;
757 struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
758 u_int8_t u3 = nfmsg->nfgen_family;
759 int err = 0;
760
761 DEBUGP("entered %s\n", __FUNCTION__);
762
763 if (nlh->nlmsg_flags & NLM_F_DUMP) {
764 u32 rlen;
765
766 if (NFNL_MSG_TYPE(nlh->nlmsg_type) ==
767 IPCTNL_MSG_CT_GET_CTRZERO) {
768#ifdef CONFIG_NF_CT_ACCT
769 if ((*errp = netlink_dump_start(ctnl, skb, nlh,
770 ctnetlink_dump_table_w,
771 ctnetlink_done)) != 0)
772 return -EINVAL;
773#else
774 return -ENOTSUPP;
775#endif
776 } else {
777 if ((*errp = netlink_dump_start(ctnl, skb, nlh,
778 ctnetlink_dump_table,
779 ctnetlink_done)) != 0)
780 return -EINVAL;
781 }
782
783 rlen = NLMSG_ALIGN(nlh->nlmsg_len);
784 if (rlen > skb->len)
785 rlen = skb->len;
786 skb_pull(skb, rlen);
787 return 0;
788 }
789
790 if (nfattr_bad_size(cda, CTA_MAX, cta_min))
791 return -EINVAL;
792
793 if (cda[CTA_TUPLE_ORIG-1])
794 err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG, u3);
795 else if (cda[CTA_TUPLE_REPLY-1])
796 err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY, u3);
797 else
798 return -EINVAL;
799
800 if (err < 0)
801 return err;
802
803 h = nf_conntrack_find_get(&tuple, NULL);
804 if (!h) {
805 DEBUGP("tuple not found in conntrack hash");
806 return -ENOENT;
807 }
808 DEBUGP("tuple found\n");
809 ct = nf_ct_tuplehash_to_ctrack(h);
810
811 err = -ENOMEM;
812 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
813 if (!skb2) {
814 nf_ct_put(ct);
815 return -ENOMEM;
816 }
817 NETLINK_CB(skb2).dst_pid = NETLINK_CB(skb).pid;
818
819 err = ctnetlink_fill_info(skb2, NETLINK_CB(skb).pid, nlh->nlmsg_seq,
820 IPCTNL_MSG_CT_NEW, 1, ct);
821 nf_ct_put(ct);
822 if (err <= 0)
823 goto free;
824
825 err = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT);
826 if (err < 0)
827 goto out;
828
829 DEBUGP("leaving\n");
830 return 0;
831
832free:
833 kfree_skb(skb2);
834out:
835 return err;
836}
837
838static inline int
839ctnetlink_change_status(struct nf_conn *ct, struct nfattr *cda[])
840{
841 unsigned long d;
842 unsigned status = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_STATUS-1]));
843 d = ct->status ^ status;
844
845 if (d & (IPS_EXPECTED|IPS_CONFIRMED|IPS_DYING))
846 /* unchangeable */
847 return -EINVAL;
848
849 if (d & IPS_SEEN_REPLY && !(status & IPS_SEEN_REPLY))
850 /* SEEN_REPLY bit can only be set */
851 return -EINVAL;
852
853
854 if (d & IPS_ASSURED && !(status & IPS_ASSURED))
855 /* ASSURED bit can only be set */
856 return -EINVAL;
857
858 if (cda[CTA_NAT-1]) {
859#ifndef CONFIG_IP_NF_NAT_NEEDED
860 return -EINVAL;
861#else
862 unsigned int hooknum;
863 struct ip_nat_range range;
864
865 if (ctnetlink_parse_nat(cda, ct, &range) < 0)
866 return -EINVAL;
867
868 DEBUGP("NAT: %u.%u.%u.%u-%u.%u.%u.%u:%u-%u\n",
869 NIPQUAD(range.min_ip), NIPQUAD(range.max_ip),
870 htons(range.min.all), htons(range.max.all));
871
872 /* This is tricky but it works. ip_nat_setup_info needs the
873 * hook number as parameter, so let's do the correct
874 * conversion and run away */
875 if (status & IPS_SRC_NAT_DONE)
876 hooknum = NF_IP_POST_ROUTING; /* IP_NAT_MANIP_SRC */
877 else if (status & IPS_DST_NAT_DONE)
878 hooknum = NF_IP_PRE_ROUTING; /* IP_NAT_MANIP_DST */
879 else
880 return -EINVAL; /* Missing NAT flags */
881
882 DEBUGP("NAT status: %lu\n",
883 status & (IPS_NAT_MASK | IPS_NAT_DONE_MASK));
884
885 if (ip_nat_initialized(ct, HOOK2MANIP(hooknum)))
886 return -EEXIST;
887 ip_nat_setup_info(ct, &range, hooknum);
888
889 DEBUGP("NAT status after setup_info: %lu\n",
890 ct->status & (IPS_NAT_MASK | IPS_NAT_DONE_MASK));
891#endif
892 }
893
894 /* Be careful here, modifying NAT bits can screw up things,
895 * so don't let users modify them directly if they don't pass
896 * ip_nat_range. */
897 ct->status |= status & ~(IPS_NAT_DONE_MASK | IPS_NAT_MASK);
898 return 0;
899}
900
901
902static inline int
903ctnetlink_change_helper(struct nf_conn *ct, struct nfattr *cda[])
904{
905 struct nf_conntrack_helper *helper;
906 char *helpname;
907 int err;
908
909 DEBUGP("entered %s\n", __FUNCTION__);
910
911 /* don't change helper of sibling connections */
912 if (ct->master)
913 return -EINVAL;
914
915 err = ctnetlink_parse_help(cda[CTA_HELP-1], &helpname);
916 if (err < 0)
917 return err;
918
919 helper = __nf_conntrack_helper_find_byname(helpname);
920 if (!helper) {
921 if (!strcmp(helpname, ""))
922 helper = NULL;
923 else
924 return -EINVAL;
925 }
926
927 if (ct->helper) {
928 if (!helper) {
929 /* we had a helper before ... */
930 nf_ct_remove_expectations(ct);
931 ct->helper = NULL;
932 } else {
933 /* need to zero data of old helper */
934 memset(&ct->help, 0, sizeof(ct->help));
935 }
936 }
937
938 ct->helper = helper;
939
940 return 0;
941}
942
943static inline int
944ctnetlink_change_timeout(struct nf_conn *ct, struct nfattr *cda[])
945{
946 u_int32_t timeout = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_TIMEOUT-1]));
947
948 if (!del_timer(&ct->timeout))
949 return -ETIME;
950
951 ct->timeout.expires = jiffies + timeout * HZ;
952 add_timer(&ct->timeout);
953
954 return 0;
955}
956
957static inline int
958ctnetlink_change_protoinfo(struct nf_conn *ct, struct nfattr *cda[])
959{
960 struct nfattr *tb[CTA_PROTOINFO_MAX], *attr = cda[CTA_PROTOINFO-1];
961 struct nf_conntrack_protocol *proto;
962 u_int16_t npt = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum;
963 u_int16_t l3num = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
964 int err = 0;
965
966 nfattr_parse_nested(tb, CTA_PROTOINFO_MAX, attr);
967
968 proto = nf_ct_proto_find_get(l3num, npt);
969
970 if (proto->from_nfattr)
971 err = proto->from_nfattr(tb, ct);
972 nf_ct_proto_put(proto);
973
974 return err;
975}
976
977static int
978ctnetlink_change_conntrack(struct nf_conn *ct, struct nfattr *cda[])
979{
980 int err;
981
982 DEBUGP("entered %s\n", __FUNCTION__);
983
984 if (cda[CTA_HELP-1]) {
985 err = ctnetlink_change_helper(ct, cda);
986 if (err < 0)
987 return err;
988 }
989
990 if (cda[CTA_TIMEOUT-1]) {
991 err = ctnetlink_change_timeout(ct, cda);
992 if (err < 0)
993 return err;
994 }
995
996 if (cda[CTA_STATUS-1]) {
997 err = ctnetlink_change_status(ct, cda);
998 if (err < 0)
999 return err;
1000 }
1001
1002 if (cda[CTA_PROTOINFO-1]) {
1003 err = ctnetlink_change_protoinfo(ct, cda);
1004 if (err < 0)
1005 return err;
1006 }
1007
1008#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
1009 if (cda[CTA_MARK-1])
1010 ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1]));
1011#endif
1012
1013 DEBUGP("all done\n");
1014 return 0;
1015}
1016
1017static int
1018ctnetlink_create_conntrack(struct nfattr *cda[],
1019 struct nf_conntrack_tuple *otuple,
1020 struct nf_conntrack_tuple *rtuple)
1021{
1022 struct nf_conn *ct;
1023 int err = -EINVAL;
1024
1025 DEBUGP("entered %s\n", __FUNCTION__);
1026
1027 ct = nf_conntrack_alloc(otuple, rtuple);
1028 if (ct == NULL || IS_ERR(ct))
1029 return -ENOMEM;
1030
1031 if (!cda[CTA_TIMEOUT-1])
1032 goto err;
1033 ct->timeout.expires = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_TIMEOUT-1]));
1034
1035 ct->timeout.expires = jiffies + ct->timeout.expires * HZ;
1036 ct->status |= IPS_CONFIRMED;
1037
1038 err = ctnetlink_change_status(ct, cda);
1039 if (err < 0)
1040 goto err;
1041
1042 if (cda[CTA_PROTOINFO-1]) {
1043 err = ctnetlink_change_protoinfo(ct, cda);
1044 if (err < 0)
1045 return err;
1046 }
1047
1048#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
1049 if (cda[CTA_MARK-1])
1050 ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1]));
1051#endif
1052
1053 ct->helper = nf_ct_helper_find_get(rtuple);
1054
1055 add_timer(&ct->timeout);
1056 nf_conntrack_hash_insert(ct);
1057
1058 if (ct->helper)
1059 nf_ct_helper_put(ct->helper);
1060
1061 DEBUGP("conntrack with id %u inserted\n", ct->id);
1062 return 0;
1063
1064err:
1065 nf_conntrack_free(ct);
1066 return err;
1067}
1068
1069static int
1070ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
1071 struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
1072{
1073 struct nf_conntrack_tuple otuple, rtuple;
1074 struct nf_conntrack_tuple_hash *h = NULL;
1075 struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
1076 u_int8_t u3 = nfmsg->nfgen_family;
1077 int err = 0;
1078
1079 DEBUGP("entered %s\n", __FUNCTION__);
1080
1081 if (nfattr_bad_size(cda, CTA_MAX, cta_min))
1082 return -EINVAL;
1083
1084 if (cda[CTA_TUPLE_ORIG-1]) {
1085 err = ctnetlink_parse_tuple(cda, &otuple, CTA_TUPLE_ORIG, u3);
1086 if (err < 0)
1087 return err;
1088 }
1089
1090 if (cda[CTA_TUPLE_REPLY-1]) {
1091 err = ctnetlink_parse_tuple(cda, &rtuple, CTA_TUPLE_REPLY, u3);
1092 if (err < 0)
1093 return err;
1094 }
1095
1096 write_lock_bh(&nf_conntrack_lock);
1097 if (cda[CTA_TUPLE_ORIG-1])
1098 h = __nf_conntrack_find(&otuple, NULL);
1099 else if (cda[CTA_TUPLE_REPLY-1])
1100 h = __nf_conntrack_find(&rtuple, NULL);
1101
1102 if (h == NULL) {
1103 write_unlock_bh(&nf_conntrack_lock);
1104 DEBUGP("no such conntrack, create new\n");
1105 err = -ENOENT;
1106 if (nlh->nlmsg_flags & NLM_F_CREATE)
1107 err = ctnetlink_create_conntrack(cda, &otuple, &rtuple);
1108 return err;
1109 }
1110 /* implicit 'else' */
1111
1112 /* we only allow nat config for new conntracks */
1113 if (cda[CTA_NAT-1]) {
1114 err = -EINVAL;
1115 goto out_unlock;
1116 }
1117
1118 /* We manipulate the conntrack inside the global conntrack table lock,
1119 * so there's no need to increase the refcount */
1120 DEBUGP("conntrack found\n");
1121 err = -EEXIST;
1122 if (!(nlh->nlmsg_flags & NLM_F_EXCL))
1123 err = ctnetlink_change_conntrack(nf_ct_tuplehash_to_ctrack(h), cda);
1124
1125out_unlock:
1126 write_unlock_bh(&nf_conntrack_lock);
1127 return err;
1128}
1129
1130/***********************************************************************
1131 * EXPECT
1132 ***********************************************************************/
1133
1134static inline int
1135ctnetlink_exp_dump_tuple(struct sk_buff *skb,
1136 const struct nf_conntrack_tuple *tuple,
1137 enum ctattr_expect type)
1138{
1139 struct nfattr *nest_parms = NFA_NEST(skb, type);
1140
1141 if (ctnetlink_dump_tuples(skb, tuple) < 0)
1142 goto nfattr_failure;
1143
1144 NFA_NEST_END(skb, nest_parms);
1145
1146 return 0;
1147
1148nfattr_failure:
1149 return -1;
1150}
1151
1152static inline int
1153ctnetlink_exp_dump_expect(struct sk_buff *skb,
1154 const struct nf_conntrack_expect *exp)
1155{
1156 struct nf_conn *master = exp->master;
1157 u_int32_t timeout = htonl((exp->timeout.expires - jiffies) / HZ);
1158 u_int32_t id = htonl(exp->id);
1159
1160 if (ctnetlink_exp_dump_tuple(skb, &exp->tuple, CTA_EXPECT_TUPLE) < 0)
1161 goto nfattr_failure;
1162 if (ctnetlink_exp_dump_tuple(skb, &exp->mask, CTA_EXPECT_MASK) < 0)
1163 goto nfattr_failure;
1164 if (ctnetlink_exp_dump_tuple(skb,
1165 &master->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
1166 CTA_EXPECT_MASTER) < 0)
1167 goto nfattr_failure;
1168
1169 NFA_PUT(skb, CTA_EXPECT_TIMEOUT, sizeof(timeout), &timeout);
1170 NFA_PUT(skb, CTA_EXPECT_ID, sizeof(u_int32_t), &id);
1171
1172 return 0;
1173
1174nfattr_failure:
1175 return -1;
1176}
1177
1178static int
1179ctnetlink_exp_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
1180 int event,
1181 int nowait,
1182 const struct nf_conntrack_expect *exp)
1183{
1184 struct nlmsghdr *nlh;
1185 struct nfgenmsg *nfmsg;
1186 unsigned char *b;
1187
1188 b = skb->tail;
1189
1190 event |= NFNL_SUBSYS_CTNETLINK_EXP << 8;
1191 nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(struct nfgenmsg));
1192 nfmsg = NLMSG_DATA(nlh);
1193
1194 nlh->nlmsg_flags = (nowait && pid) ? NLM_F_MULTI : 0;
1195 nfmsg->nfgen_family = exp->tuple.src.l3num;
1196 nfmsg->version = NFNETLINK_V0;
1197 nfmsg->res_id = 0;
1198
1199 if (ctnetlink_exp_dump_expect(skb, exp) < 0)
1200 goto nfattr_failure;
1201
1202 nlh->nlmsg_len = skb->tail - b;
1203 return skb->len;
1204
1205nlmsg_failure:
1206nfattr_failure:
1207 skb_trim(skb, b - skb->data);
1208 return -1;
1209}
1210
1211#ifdef CONFIG_NF_CONNTRACK_EVENTS
1212static int ctnetlink_expect_event(struct notifier_block *this,
1213 unsigned long events, void *ptr)
1214{
1215 struct nlmsghdr *nlh;
1216 struct nfgenmsg *nfmsg;
1217 struct nf_conntrack_expect *exp = (struct nf_conntrack_expect *)ptr;
1218 struct sk_buff *skb;
1219 unsigned int type;
1220 unsigned char *b;
1221 int flags = 0;
1222
1223 if (events & IPEXP_NEW) {
1224 type = IPCTNL_MSG_EXP_NEW;
1225 flags = NLM_F_CREATE|NLM_F_EXCL;
1226 } else
1227 return NOTIFY_DONE;
1228
1229 skb = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC);
1230 if (!skb)
1231 return NOTIFY_DONE;
1232
1233 b = skb->tail;
1234
1235 type |= NFNL_SUBSYS_CTNETLINK << 8;
1236 nlh = NLMSG_PUT(skb, 0, 0, type, sizeof(struct nfgenmsg));
1237 nfmsg = NLMSG_DATA(nlh);
1238
1239 nlh->nlmsg_flags = flags;
1240 nfmsg->nfgen_family = exp->tuple.src.l3num;
1241 nfmsg->version = NFNETLINK_V0;
1242 nfmsg->res_id = 0;
1243
1244 if (ctnetlink_exp_dump_expect(skb, exp) < 0)
1245 goto nfattr_failure;
1246
1247 nlh->nlmsg_len = skb->tail - b;
1248 nfnetlink_send(skb, 0, NFNLGRP_CONNTRACK_EXP_NEW, 0);
1249 return NOTIFY_DONE;
1250
1251nlmsg_failure:
1252nfattr_failure:
1253 kfree_skb(skb);
1254 return NOTIFY_DONE;
1255}
1256#endif
1257
1258static int
1259ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
1260{
1261 struct nf_conntrack_expect *exp = NULL;
1262 struct list_head *i;
1263 u_int32_t *id = (u_int32_t *) &cb->args[0];
1264 struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh);
1265 u_int8_t l3proto = nfmsg->nfgen_family;
1266
1267 DEBUGP("entered %s, last id=%llu\n", __FUNCTION__, *id);
1268
1269 read_lock_bh(&nf_conntrack_lock);
1270 list_for_each_prev(i, &nf_conntrack_expect_list) {
1271 exp = (struct nf_conntrack_expect *) i;
1272 if (l3proto && exp->tuple.src.l3num != l3proto)
1273 continue;
1274 if (exp->id <= *id)
1275 continue;
1276 if (ctnetlink_exp_fill_info(skb, NETLINK_CB(cb->skb).pid,
1277 cb->nlh->nlmsg_seq,
1278 IPCTNL_MSG_EXP_NEW,
1279 1, exp) < 0)
1280 goto out;
1281 *id = exp->id;
1282 }
1283out:
1284 read_unlock_bh(&nf_conntrack_lock);
1285
1286 DEBUGP("leaving, last id=%llu\n", *id);
1287
1288 return skb->len;
1289}
1290
1291static const size_t cta_min_exp[CTA_EXPECT_MAX] = {
1292 [CTA_EXPECT_TIMEOUT-1] = sizeof(u_int32_t),
1293 [CTA_EXPECT_ID-1] = sizeof(u_int32_t)
1294};
1295
1296static int
1297ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
1298 struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
1299{
1300 struct nf_conntrack_tuple tuple;
1301 struct nf_conntrack_expect *exp;
1302 struct sk_buff *skb2;
1303 struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
1304 u_int8_t u3 = nfmsg->nfgen_family;
1305 int err = 0;
1306
1307 DEBUGP("entered %s\n", __FUNCTION__);
1308
1309 if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp))
1310 return -EINVAL;
1311
1312 if (nlh->nlmsg_flags & NLM_F_DUMP) {
1313 u32 rlen;
1314
1315 if ((*errp = netlink_dump_start(ctnl, skb, nlh,
1316 ctnetlink_exp_dump_table,
1317 ctnetlink_done)) != 0)
1318 return -EINVAL;
1319 rlen = NLMSG_ALIGN(nlh->nlmsg_len);
1320 if (rlen > skb->len)
1321 rlen = skb->len;
1322 skb_pull(skb, rlen);
1323 return 0;
1324 }
1325
1326 if (cda[CTA_EXPECT_MASTER-1])
1327 err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_MASTER, u3);
1328 else
1329 return -EINVAL;
1330
1331 if (err < 0)
1332 return err;
1333
1334 exp = nf_conntrack_expect_find(&tuple);
1335 if (!exp)
1336 return -ENOENT;
1337
1338 if (cda[CTA_EXPECT_ID-1]) {
1339 u_int32_t id = *(u_int32_t *)NFA_DATA(cda[CTA_EXPECT_ID-1]);
1340 if (exp->id != ntohl(id)) {
1341 nf_conntrack_expect_put(exp);
1342 return -ENOENT;
1343 }
1344 }
1345
1346 err = -ENOMEM;
1347 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
1348 if (!skb2)
1349 goto out;
1350 NETLINK_CB(skb2).dst_pid = NETLINK_CB(skb).pid;
1351
1352 err = ctnetlink_exp_fill_info(skb2, NETLINK_CB(skb).pid,
1353 nlh->nlmsg_seq, IPCTNL_MSG_EXP_NEW,
1354 1, exp);
1355 if (err <= 0)
1356 goto free;
1357
1358 nf_conntrack_expect_put(exp);
1359
1360 return netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT);
1361
1362free:
1363 kfree_skb(skb2);
1364out:
1365 nf_conntrack_expect_put(exp);
1366 return err;
1367}
1368
1369static int
1370ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
1371 struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
1372{
1373 struct nf_conntrack_expect *exp, *tmp;
1374 struct nf_conntrack_tuple tuple;
1375 struct nf_conntrack_helper *h;
1376 struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
1377 u_int8_t u3 = nfmsg->nfgen_family;
1378 int err;
1379
1380 if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp))
1381 return -EINVAL;
1382
1383 if (cda[CTA_EXPECT_TUPLE-1]) {
1384 /* delete a single expect by tuple */
1385 err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE, u3);
1386 if (err < 0)
1387 return err;
1388
1389 /* bump usage count to 2 */
1390 exp = nf_conntrack_expect_find(&tuple);
1391 if (!exp)
1392 return -ENOENT;
1393
1394 if (cda[CTA_EXPECT_ID-1]) {
1395 u_int32_t id =
1396 *(u_int32_t *)NFA_DATA(cda[CTA_EXPECT_ID-1]);
1397 if (exp->id != ntohl(id)) {
1398 nf_conntrack_expect_put(exp);
1399 return -ENOENT;
1400 }
1401 }
1402
1403 /* after list removal, usage count == 1 */
1404 nf_conntrack_unexpect_related(exp);
1405 /* have to put what we 'get' above.
1406 * after this line usage count == 0 */
1407 nf_conntrack_expect_put(exp);
1408 } else if (cda[CTA_EXPECT_HELP_NAME-1]) {
1409 char *name = NFA_DATA(cda[CTA_EXPECT_HELP_NAME-1]);
1410
1411 /* delete all expectations for this helper */
1412 write_lock_bh(&nf_conntrack_lock);
1413 h = __nf_conntrack_helper_find_byname(name);
1414 if (!h) {
1415 write_unlock_bh(&nf_conntrack_lock);
1416 return -EINVAL;
1417 }
1418 list_for_each_entry_safe(exp, tmp, &nf_conntrack_expect_list,
1419 list) {
1420 if (exp->master->helper == h
1421 && del_timer(&exp->timeout)) {
1422 nf_ct_unlink_expect(exp);
1423 nf_conntrack_expect_put(exp);
1424 }
1425 }
1426 write_unlock_bh(&nf_conntrack_lock);
1427 } else {
1428 /* This basically means we have to flush everything*/
1429 write_lock_bh(&nf_conntrack_lock);
1430 list_for_each_entry_safe(exp, tmp, &nf_conntrack_expect_list,
1431 list) {
1432 if (del_timer(&exp->timeout)) {
1433 nf_ct_unlink_expect(exp);
1434 nf_conntrack_expect_put(exp);
1435 }
1436 }
1437 write_unlock_bh(&nf_conntrack_lock);
1438 }
1439
1440 return 0;
1441}
1442static int
1443ctnetlink_change_expect(struct nf_conntrack_expect *x, struct nfattr *cda[])
1444{
1445 return -EOPNOTSUPP;
1446}
1447
1448static int
1449ctnetlink_create_expect(struct nfattr *cda[], u_int8_t u3)
1450{
1451 struct nf_conntrack_tuple tuple, mask, master_tuple;
1452 struct nf_conntrack_tuple_hash *h = NULL;
1453 struct nf_conntrack_expect *exp;
1454 struct nf_conn *ct;
1455 int err = 0;
1456
1457 DEBUGP("entered %s\n", __FUNCTION__);
1458
1459 /* caller guarantees that those three CTA_EXPECT_* exist */
1460 err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE, u3);
1461 if (err < 0)
1462 return err;
1463 err = ctnetlink_parse_tuple(cda, &mask, CTA_EXPECT_MASK, u3);
1464 if (err < 0)
1465 return err;
1466 err = ctnetlink_parse_tuple(cda, &master_tuple, CTA_EXPECT_MASTER, u3);
1467 if (err < 0)
1468 return err;
1469
1470 /* Look for master conntrack of this expectation */
1471 h = nf_conntrack_find_get(&master_tuple, NULL);
1472 if (!h)
1473 return -ENOENT;
1474 ct = nf_ct_tuplehash_to_ctrack(h);
1475
1476 if (!ct->helper) {
1477 /* such conntrack hasn't got any helper, abort */
1478 err = -EINVAL;
1479 goto out;
1480 }
1481
1482 exp = nf_conntrack_expect_alloc(ct);
1483 if (!exp) {
1484 err = -ENOMEM;
1485 goto out;
1486 }
1487
1488 exp->expectfn = NULL;
1489 exp->flags = 0;
1490 exp->master = ct;
1491 memcpy(&exp->tuple, &tuple, sizeof(struct nf_conntrack_tuple));
1492 memcpy(&exp->mask, &mask, sizeof(struct nf_conntrack_tuple));
1493
1494 err = nf_conntrack_expect_related(exp);
1495 nf_conntrack_expect_put(exp);
1496
1497out:
1498 nf_ct_put(nf_ct_tuplehash_to_ctrack(h));
1499 return err;
1500}
1501
1502static int
1503ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
1504 struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
1505{
1506 struct nf_conntrack_tuple tuple;
1507 struct nf_conntrack_expect *exp;
1508 struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
1509 u_int8_t u3 = nfmsg->nfgen_family;
1510 int err = 0;
1511
1512 DEBUGP("entered %s\n", __FUNCTION__);
1513
1514 if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp))
1515 return -EINVAL;
1516
1517 if (!cda[CTA_EXPECT_TUPLE-1]
1518 || !cda[CTA_EXPECT_MASK-1]
1519 || !cda[CTA_EXPECT_MASTER-1])
1520 return -EINVAL;
1521
1522 err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE, u3);
1523 if (err < 0)
1524 return err;
1525
1526 write_lock_bh(&nf_conntrack_lock);
1527 exp = __nf_conntrack_expect_find(&tuple);
1528
1529 if (!exp) {
1530 write_unlock_bh(&nf_conntrack_lock);
1531 err = -ENOENT;
1532 if (nlh->nlmsg_flags & NLM_F_CREATE)
1533 err = ctnetlink_create_expect(cda, u3);
1534 return err;
1535 }
1536
1537 err = -EEXIST;
1538 if (!(nlh->nlmsg_flags & NLM_F_EXCL))
1539 err = ctnetlink_change_expect(exp, cda);
1540 write_unlock_bh(&nf_conntrack_lock);
1541
1542 DEBUGP("leaving\n");
1543
1544 return err;
1545}
1546
1547#ifdef CONFIG_NF_CONNTRACK_EVENTS
1548static struct notifier_block ctnl_notifier = {
1549 .notifier_call = ctnetlink_conntrack_event,
1550};
1551
1552static struct notifier_block ctnl_notifier_exp = {
1553 .notifier_call = ctnetlink_expect_event,
1554};
1555#endif
1556
1557static struct nfnl_callback ctnl_cb[IPCTNL_MSG_MAX] = {
1558 [IPCTNL_MSG_CT_NEW] = { .call = ctnetlink_new_conntrack,
1559 .attr_count = CTA_MAX, },
1560 [IPCTNL_MSG_CT_GET] = { .call = ctnetlink_get_conntrack,
1561 .attr_count = CTA_MAX, },
1562 [IPCTNL_MSG_CT_DELETE] = { .call = ctnetlink_del_conntrack,
1563 .attr_count = CTA_MAX, },
1564 [IPCTNL_MSG_CT_GET_CTRZERO] = { .call = ctnetlink_get_conntrack,
1565 .attr_count = CTA_MAX, },
1566};
1567
1568static struct nfnl_callback ctnl_exp_cb[IPCTNL_MSG_EXP_MAX] = {
1569 [IPCTNL_MSG_EXP_GET] = { .call = ctnetlink_get_expect,
1570 .attr_count = CTA_EXPECT_MAX, },
1571 [IPCTNL_MSG_EXP_NEW] = { .call = ctnetlink_new_expect,
1572 .attr_count = CTA_EXPECT_MAX, },
1573 [IPCTNL_MSG_EXP_DELETE] = { .call = ctnetlink_del_expect,
1574 .attr_count = CTA_EXPECT_MAX, },
1575};
1576
1577static struct nfnetlink_subsystem ctnl_subsys = {
1578 .name = "conntrack",
1579 .subsys_id = NFNL_SUBSYS_CTNETLINK,
1580 .cb_count = IPCTNL_MSG_MAX,
1581 .cb = ctnl_cb,
1582};
1583
1584static struct nfnetlink_subsystem ctnl_exp_subsys = {
1585 .name = "conntrack_expect",
1586 .subsys_id = NFNL_SUBSYS_CTNETLINK_EXP,
1587 .cb_count = IPCTNL_MSG_EXP_MAX,
1588 .cb = ctnl_exp_cb,
1589};
1590
1591MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK);
1592
1593static int __init ctnetlink_init(void)
1594{
1595 int ret;
1596
1597 printk("ctnetlink v%s: registering with nfnetlink.\n", version);
1598 ret = nfnetlink_subsys_register(&ctnl_subsys);
1599 if (ret < 0) {
1600 printk("ctnetlink_init: cannot register with nfnetlink.\n");
1601 goto err_out;
1602 }
1603
1604 ret = nfnetlink_subsys_register(&ctnl_exp_subsys);
1605 if (ret < 0) {
1606 printk("ctnetlink_init: cannot register exp with nfnetlink.\n");
1607 goto err_unreg_subsys;
1608 }
1609
1610#ifdef CONFIG_NF_CONNTRACK_EVENTS
1611 ret = nf_conntrack_register_notifier(&ctnl_notifier);
1612 if (ret < 0) {
1613 printk("ctnetlink_init: cannot register notifier.\n");
1614 goto err_unreg_exp_subsys;
1615 }
1616
1617 ret = nf_conntrack_expect_register_notifier(&ctnl_notifier_exp);
1618 if (ret < 0) {
1619 printk("ctnetlink_init: cannot expect register notifier.\n");
1620 goto err_unreg_notifier;
1621 }
1622#endif
1623
1624 return 0;
1625
1626#ifdef CONFIG_NF_CONNTRACK_EVENTS
1627err_unreg_notifier:
1628 nf_conntrack_unregister_notifier(&ctnl_notifier);
1629err_unreg_exp_subsys:
1630 nfnetlink_subsys_unregister(&ctnl_exp_subsys);
1631#endif
1632err_unreg_subsys:
1633 nfnetlink_subsys_unregister(&ctnl_subsys);
1634err_out:
1635 return ret;
1636}
1637
1638static void __exit ctnetlink_exit(void)
1639{
1640 printk("ctnetlink: unregistering from nfnetlink.\n");
1641
1642#ifdef CONFIG_NF_CONNTRACK_EVENTS
1643 nf_conntrack_unregister_notifier(&ctnl_notifier_exp);
1644 nf_conntrack_unregister_notifier(&ctnl_notifier);
1645#endif
1646
1647 nfnetlink_subsys_unregister(&ctnl_exp_subsys);
1648 nfnetlink_subsys_unregister(&ctnl_subsys);
1649 return;
1650}
1651
1652module_init(ctnetlink_init);
1653module_exit(ctnetlink_exit);
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index 6035633d8225..6167137a5cb5 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -1147,6 +1147,63 @@ static int tcp_new(struct nf_conn *conntrack,
1147 receiver->td_scale); 1147 receiver->td_scale);
1148 return 1; 1148 return 1;
1149} 1149}
1150
1151#if defined(CONFIG_NF_CT_NETLINK) || \
1152 defined(CONFIG_NF_CT_NETLINK_MODULE)
1153
1154#include <linux/netfilter/nfnetlink.h>
1155#include <linux/netfilter/nfnetlink_conntrack.h>
1156
1157static int tcp_to_nfattr(struct sk_buff *skb, struct nfattr *nfa,
1158 const struct nf_conn *ct)
1159{
1160 struct nfattr *nest_parms;
1161
1162 read_lock_bh(&tcp_lock);
1163 nest_parms = NFA_NEST(skb, CTA_PROTOINFO_TCP);
1164 NFA_PUT(skb, CTA_PROTOINFO_TCP_STATE, sizeof(u_int8_t),
1165 &ct->proto.tcp.state);
1166 read_unlock_bh(&tcp_lock);
1167
1168 NFA_NEST_END(skb, nest_parms);
1169
1170 return 0;
1171
1172nfattr_failure:
1173 read_unlock_bh(&tcp_lock);
1174 return -1;
1175}
1176
1177static const size_t cta_min_tcp[CTA_PROTOINFO_TCP_MAX] = {
1178 [CTA_PROTOINFO_TCP_STATE-1] = sizeof(u_int8_t),
1179};
1180
1181static int nfattr_to_tcp(struct nfattr *cda[], struct nf_conn *ct)
1182{
1183 struct nfattr *attr = cda[CTA_PROTOINFO_TCP-1];
1184 struct nfattr *tb[CTA_PROTOINFO_TCP_MAX];
1185
1186 /* updates could not contain anything about the private
1187 * protocol info, in that case skip the parsing */
1188 if (!attr)
1189 return 0;
1190
1191 nfattr_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, attr);
1192
1193 if (nfattr_bad_size(tb, CTA_PROTOINFO_TCP_MAX, cta_min_tcp))
1194 return -EINVAL;
1195
1196 if (!tb[CTA_PROTOINFO_TCP_STATE-1])
1197 return -EINVAL;
1198
1199 write_lock_bh(&tcp_lock);
1200 ct->proto.tcp.state =
1201 *(u_int8_t *)NFA_DATA(tb[CTA_PROTOINFO_TCP_STATE-1]);
1202 write_unlock_bh(&tcp_lock);
1203
1204 return 0;
1205}
1206#endif
1150 1207
1151struct nf_conntrack_protocol nf_conntrack_protocol_tcp4 = 1208struct nf_conntrack_protocol nf_conntrack_protocol_tcp4 =
1152{ 1209{
@@ -1160,6 +1217,13 @@ struct nf_conntrack_protocol nf_conntrack_protocol_tcp4 =
1160 .packet = tcp_packet, 1217 .packet = tcp_packet,
1161 .new = tcp_new, 1218 .new = tcp_new,
1162 .error = tcp_error4, 1219 .error = tcp_error4,
1220#if defined(CONFIG_NF_CT_NETLINK) || \
1221 defined(CONFIG_NF_CT_NETLINK_MODULE)
1222 .to_nfattr = tcp_to_nfattr,
1223 .from_nfattr = nfattr_to_tcp,
1224 .tuple_to_nfattr = nf_ct_port_tuple_to_nfattr,
1225 .nfattr_to_tuple = nf_ct_port_nfattr_to_tuple,
1226#endif
1163}; 1227};
1164 1228
1165struct nf_conntrack_protocol nf_conntrack_protocol_tcp6 = 1229struct nf_conntrack_protocol nf_conntrack_protocol_tcp6 =
@@ -1174,6 +1238,13 @@ struct nf_conntrack_protocol nf_conntrack_protocol_tcp6 =
1174 .packet = tcp_packet, 1238 .packet = tcp_packet,
1175 .new = tcp_new, 1239 .new = tcp_new,
1176 .error = tcp_error6, 1240 .error = tcp_error6,
1241#if defined(CONFIG_NF_CT_NETLINK) || \
1242 defined(CONFIG_NF_CT_NETLINK_MODULE)
1243 .to_nfattr = tcp_to_nfattr,
1244 .from_nfattr = nfattr_to_tcp,
1245 .tuple_to_nfattr = nf_ct_port_tuple_to_nfattr,
1246 .nfattr_to_tuple = nf_ct_port_nfattr_to_tuple,
1247#endif
1177}; 1248};
1178 1249
1179EXPORT_SYMBOL(nf_conntrack_protocol_tcp4); 1250EXPORT_SYMBOL(nf_conntrack_protocol_tcp4);
diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c
index 3cae7ce420dd..1a592a556182 100644
--- a/net/netfilter/nf_conntrack_proto_udp.c
+++ b/net/netfilter/nf_conntrack_proto_udp.c
@@ -196,6 +196,11 @@ struct nf_conntrack_protocol nf_conntrack_protocol_udp4 =
196 .packet = udp_packet, 196 .packet = udp_packet,
197 .new = udp_new, 197 .new = udp_new,
198 .error = udp_error4, 198 .error = udp_error4,
199#if defined(CONFIG_NF_CT_NETLINK) || \
200 defined(CONFIG_NF_CT_NETLINK_MODULE)
201 .tuple_to_nfattr = nf_ct_port_tuple_to_nfattr,
202 .nfattr_to_tuple = nf_ct_port_nfattr_to_tuple,
203#endif
199}; 204};
200 205
201struct nf_conntrack_protocol nf_conntrack_protocol_udp6 = 206struct nf_conntrack_protocol nf_conntrack_protocol_udp6 =
@@ -210,6 +215,11 @@ struct nf_conntrack_protocol nf_conntrack_protocol_udp6 =
210 .packet = udp_packet, 215 .packet = udp_packet,
211 .new = udp_new, 216 .new = udp_new,
212 .error = udp_error6, 217 .error = udp_error6,
218#if defined(CONFIG_NF_CT_NETLINK) || \
219 defined(CONFIG_NF_CT_NETLINK_MODULE)
220 .tuple_to_nfattr = nf_ct_port_tuple_to_nfattr,
221 .nfattr_to_tuple = nf_ct_port_nfattr_to_tuple,
222#endif
213}; 223};
214 224
215EXPORT_SYMBOL(nf_conntrack_protocol_udp4); 225EXPORT_SYMBOL(nf_conntrack_protocol_udp4);
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index 5af381f9fe3d..d17e42b28c79 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -161,14 +161,14 @@ static int ct_seq_show(struct seq_file *s, void *v)
161 if (NF_CT_DIRECTION(hash)) 161 if (NF_CT_DIRECTION(hash))
162 return 0; 162 return 0;
163 163
164 l3proto = nf_ct_find_l3proto(conntrack->tuplehash[IP_CT_DIR_ORIGINAL] 164 l3proto = __nf_ct_l3proto_find(conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
165 .tuple.src.l3num); 165 .tuple.src.l3num);
166 166
167 NF_CT_ASSERT(l3proto); 167 NF_CT_ASSERT(l3proto);
168 proto = nf_ct_find_proto(conntrack->tuplehash[IP_CT_DIR_ORIGINAL] 168 proto = __nf_ct_proto_find(conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
169 .tuple.src.l3num, 169 .tuple.src.l3num,
170 conntrack->tuplehash[IP_CT_DIR_ORIGINAL] 170 conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
171 .tuple.dst.protonum); 171 .tuple.dst.protonum);
172 NF_CT_ASSERT(proto); 172 NF_CT_ASSERT(proto);
173 173
174 if (seq_printf(s, "%-8s %u %-8s %u %ld ", 174 if (seq_printf(s, "%-8s %u %-8s %u %ld ",
@@ -307,9 +307,9 @@ static int exp_seq_show(struct seq_file *s, void *v)
307 expect->tuple.src.l3num, 307 expect->tuple.src.l3num,
308 expect->tuple.dst.protonum); 308 expect->tuple.dst.protonum);
309 print_tuple(s, &expect->tuple, 309 print_tuple(s, &expect->tuple,
310 nf_ct_find_l3proto(expect->tuple.src.l3num), 310 __nf_ct_l3proto_find(expect->tuple.src.l3num),
311 nf_ct_find_proto(expect->tuple.src.l3num, 311 __nf_ct_proto_find(expect->tuple.src.l3num,
312 expect->tuple.dst.protonum)); 312 expect->tuple.dst.protonum));
313 return seq_putc(s, '\n'); 313 return seq_putc(s, '\n');
314} 314}
315 315
@@ -847,7 +847,11 @@ EXPORT_SYMBOL(nf_conntrack_helper_unregister);
847EXPORT_SYMBOL(nf_ct_iterate_cleanup); 847EXPORT_SYMBOL(nf_ct_iterate_cleanup);
848EXPORT_SYMBOL(__nf_ct_refresh_acct); 848EXPORT_SYMBOL(__nf_ct_refresh_acct);
849EXPORT_SYMBOL(nf_ct_protos); 849EXPORT_SYMBOL(nf_ct_protos);
850EXPORT_SYMBOL(nf_ct_find_proto); 850EXPORT_SYMBOL(__nf_ct_proto_find);
851EXPORT_SYMBOL(nf_ct_proto_find_get);
852EXPORT_SYMBOL(nf_ct_proto_put);
853EXPORT_SYMBOL(nf_ct_l3proto_find_get);
854EXPORT_SYMBOL(nf_ct_l3proto_put);
851EXPORT_SYMBOL(nf_ct_l3protos); 855EXPORT_SYMBOL(nf_ct_l3protos);
852EXPORT_SYMBOL(nf_conntrack_expect_alloc); 856EXPORT_SYMBOL(nf_conntrack_expect_alloc);
853EXPORT_SYMBOL(nf_conntrack_expect_put); 857EXPORT_SYMBOL(nf_conntrack_expect_put);
@@ -867,3 +871,21 @@ EXPORT_SYMBOL(nf_ct_get_tuple);
867EXPORT_SYMBOL(nf_ct_invert_tuple); 871EXPORT_SYMBOL(nf_ct_invert_tuple);
868EXPORT_SYMBOL(nf_conntrack_in); 872EXPORT_SYMBOL(nf_conntrack_in);
869EXPORT_SYMBOL(__nf_conntrack_attach); 873EXPORT_SYMBOL(__nf_conntrack_attach);
874EXPORT_SYMBOL(nf_conntrack_alloc);
875EXPORT_SYMBOL(nf_conntrack_free);
876EXPORT_SYMBOL(nf_conntrack_flush);
877EXPORT_SYMBOL(nf_ct_remove_expectations);
878EXPORT_SYMBOL(nf_ct_helper_find_get);
879EXPORT_SYMBOL(nf_ct_helper_put);
880EXPORT_SYMBOL(__nf_conntrack_helper_find_byname);
881EXPORT_SYMBOL(__nf_conntrack_find);
882EXPORT_SYMBOL(nf_ct_unlink_expect);
883EXPORT_SYMBOL(nf_conntrack_hash_insert);
884EXPORT_SYMBOL(__nf_conntrack_expect_find);
885EXPORT_SYMBOL(nf_conntrack_expect_find);
886EXPORT_SYMBOL(nf_conntrack_expect_list);
887#if defined(CONFIG_NF_CT_NETLINK) || \
888 defined(CONFIG_NF_CT_NETLINK_MODULE)
889EXPORT_SYMBOL(nf_ct_port_tuple_to_nfattr);
890EXPORT_SYMBOL(nf_ct_port_nfattr_to_tuple);
891#endif
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index 55afdda3d940..18ed9c5d209c 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -345,6 +345,10 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
345 struct nfqnl_msg_packet_hdr pmsg; 345 struct nfqnl_msg_packet_hdr pmsg;
346 struct nlmsghdr *nlh; 346 struct nlmsghdr *nlh;
347 struct nfgenmsg *nfmsg; 347 struct nfgenmsg *nfmsg;
348 struct nf_info *entinf = entry->info;
349 struct sk_buff *entskb = entry->skb;
350 struct net_device *indev;
351 struct net_device *outdev;
348 unsigned int tmp_uint; 352 unsigned int tmp_uint;
349 353
350 QDEBUG("entered\n"); 354 QDEBUG("entered\n");
@@ -361,6 +365,8 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
361 + NLMSG_SPACE(sizeof(struct nfqnl_msg_packet_hw)) 365 + NLMSG_SPACE(sizeof(struct nfqnl_msg_packet_hw))
362 + NLMSG_SPACE(sizeof(struct nfqnl_msg_packet_timestamp)); 366 + NLMSG_SPACE(sizeof(struct nfqnl_msg_packet_timestamp));
363 367
368 outdev = entinf->outdev;
369
364 spin_lock_bh(&queue->lock); 370 spin_lock_bh(&queue->lock);
365 371
366 switch (queue->copy_mode) { 372 switch (queue->copy_mode) {
@@ -370,15 +376,15 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
370 break; 376 break;
371 377
372 case NFQNL_COPY_PACKET: 378 case NFQNL_COPY_PACKET:
373 if (entry->skb->ip_summed == CHECKSUM_HW && 379 if (entskb->ip_summed == CHECKSUM_HW &&
374 (*errp = skb_checksum_help(entry->skb, 380 (*errp = skb_checksum_help(entskb,
375 entry->info->outdev == NULL))) { 381 outdev == NULL))) {
376 spin_unlock_bh(&queue->lock); 382 spin_unlock_bh(&queue->lock);
377 return NULL; 383 return NULL;
378 } 384 }
379 if (queue->copy_range == 0 385 if (queue->copy_range == 0
380 || queue->copy_range > entry->skb->len) 386 || queue->copy_range > entskb->len)
381 data_len = entry->skb->len; 387 data_len = entskb->len;
382 else 388 else
383 data_len = queue->copy_range; 389 data_len = queue->copy_range;
384 390
@@ -402,29 +408,30 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
402 NFNL_SUBSYS_QUEUE << 8 | NFQNL_MSG_PACKET, 408 NFNL_SUBSYS_QUEUE << 8 | NFQNL_MSG_PACKET,
403 sizeof(struct nfgenmsg)); 409 sizeof(struct nfgenmsg));
404 nfmsg = NLMSG_DATA(nlh); 410 nfmsg = NLMSG_DATA(nlh);
405 nfmsg->nfgen_family = entry->info->pf; 411 nfmsg->nfgen_family = entinf->pf;
406 nfmsg->version = NFNETLINK_V0; 412 nfmsg->version = NFNETLINK_V0;
407 nfmsg->res_id = htons(queue->queue_num); 413 nfmsg->res_id = htons(queue->queue_num);
408 414
409 pmsg.packet_id = htonl(entry->id); 415 pmsg.packet_id = htonl(entry->id);
410 pmsg.hw_protocol = htons(entry->skb->protocol); 416 pmsg.hw_protocol = htons(entskb->protocol);
411 pmsg.hook = entry->info->hook; 417 pmsg.hook = entinf->hook;
412 418
413 NFA_PUT(skb, NFQA_PACKET_HDR, sizeof(pmsg), &pmsg); 419 NFA_PUT(skb, NFQA_PACKET_HDR, sizeof(pmsg), &pmsg);
414 420
415 if (entry->info->indev) { 421 indev = entinf->indev;
416 tmp_uint = htonl(entry->info->indev->ifindex); 422 if (indev) {
423 tmp_uint = htonl(indev->ifindex);
417#ifndef CONFIG_BRIDGE_NETFILTER 424#ifndef CONFIG_BRIDGE_NETFILTER
418 NFA_PUT(skb, NFQA_IFINDEX_INDEV, sizeof(tmp_uint), &tmp_uint); 425 NFA_PUT(skb, NFQA_IFINDEX_INDEV, sizeof(tmp_uint), &tmp_uint);
419#else 426#else
420 if (entry->info->pf == PF_BRIDGE) { 427 if (entinf->pf == PF_BRIDGE) {
421 /* Case 1: indev is physical input device, we need to 428 /* Case 1: indev is physical input device, we need to
422 * look for bridge group (when called from 429 * look for bridge group (when called from
423 * netfilter_bridge) */ 430 * netfilter_bridge) */
424 NFA_PUT(skb, NFQA_IFINDEX_PHYSINDEV, sizeof(tmp_uint), 431 NFA_PUT(skb, NFQA_IFINDEX_PHYSINDEV, sizeof(tmp_uint),
425 &tmp_uint); 432 &tmp_uint);
426 /* this is the bridge group "brX" */ 433 /* this is the bridge group "brX" */
427 tmp_uint = htonl(entry->info->indev->br_port->br->dev->ifindex); 434 tmp_uint = htonl(indev->br_port->br->dev->ifindex);
428 NFA_PUT(skb, NFQA_IFINDEX_INDEV, sizeof(tmp_uint), 435 NFA_PUT(skb, NFQA_IFINDEX_INDEV, sizeof(tmp_uint),
429 &tmp_uint); 436 &tmp_uint);
430 } else { 437 } else {
@@ -432,9 +439,9 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
432 * physical device (when called from ipv4) */ 439 * physical device (when called from ipv4) */
433 NFA_PUT(skb, NFQA_IFINDEX_INDEV, sizeof(tmp_uint), 440 NFA_PUT(skb, NFQA_IFINDEX_INDEV, sizeof(tmp_uint),
434 &tmp_uint); 441 &tmp_uint);
435 if (entry->skb->nf_bridge 442 if (entskb->nf_bridge
436 && entry->skb->nf_bridge->physindev) { 443 && entskb->nf_bridge->physindev) {
437 tmp_uint = htonl(entry->skb->nf_bridge->physindev->ifindex); 444 tmp_uint = htonl(entskb->nf_bridge->physindev->ifindex);
438 NFA_PUT(skb, NFQA_IFINDEX_PHYSINDEV, 445 NFA_PUT(skb, NFQA_IFINDEX_PHYSINDEV,
439 sizeof(tmp_uint), &tmp_uint); 446 sizeof(tmp_uint), &tmp_uint);
440 } 447 }
@@ -442,19 +449,19 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
442#endif 449#endif
443 } 450 }
444 451
445 if (entry->info->outdev) { 452 if (outdev) {
446 tmp_uint = htonl(entry->info->outdev->ifindex); 453 tmp_uint = htonl(outdev->ifindex);
447#ifndef CONFIG_BRIDGE_NETFILTER 454#ifndef CONFIG_BRIDGE_NETFILTER
448 NFA_PUT(skb, NFQA_IFINDEX_OUTDEV, sizeof(tmp_uint), &tmp_uint); 455 NFA_PUT(skb, NFQA_IFINDEX_OUTDEV, sizeof(tmp_uint), &tmp_uint);
449#else 456#else
450 if (entry->info->pf == PF_BRIDGE) { 457 if (entinf->pf == PF_BRIDGE) {
451 /* Case 1: outdev is physical output device, we need to 458 /* Case 1: outdev is physical output device, we need to
452 * look for bridge group (when called from 459 * look for bridge group (when called from
453 * netfilter_bridge) */ 460 * netfilter_bridge) */
454 NFA_PUT(skb, NFQA_IFINDEX_PHYSOUTDEV, sizeof(tmp_uint), 461 NFA_PUT(skb, NFQA_IFINDEX_PHYSOUTDEV, sizeof(tmp_uint),
455 &tmp_uint); 462 &tmp_uint);
456 /* this is the bridge group "brX" */ 463 /* this is the bridge group "brX" */
457 tmp_uint = htonl(entry->info->outdev->br_port->br->dev->ifindex); 464 tmp_uint = htonl(outdev->br_port->br->dev->ifindex);
458 NFA_PUT(skb, NFQA_IFINDEX_OUTDEV, sizeof(tmp_uint), 465 NFA_PUT(skb, NFQA_IFINDEX_OUTDEV, sizeof(tmp_uint),
459 &tmp_uint); 466 &tmp_uint);
460 } else { 467 } else {
@@ -462,9 +469,9 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
462 * physical output device (when called from ipv4) */ 469 * physical output device (when called from ipv4) */
463 NFA_PUT(skb, NFQA_IFINDEX_OUTDEV, sizeof(tmp_uint), 470 NFA_PUT(skb, NFQA_IFINDEX_OUTDEV, sizeof(tmp_uint),
464 &tmp_uint); 471 &tmp_uint);
465 if (entry->skb->nf_bridge 472 if (entskb->nf_bridge
466 && entry->skb->nf_bridge->physoutdev) { 473 && entskb->nf_bridge->physoutdev) {
467 tmp_uint = htonl(entry->skb->nf_bridge->physoutdev->ifindex); 474 tmp_uint = htonl(entskb->nf_bridge->physoutdev->ifindex);
468 NFA_PUT(skb, NFQA_IFINDEX_PHYSOUTDEV, 475 NFA_PUT(skb, NFQA_IFINDEX_PHYSOUTDEV,
469 sizeof(tmp_uint), &tmp_uint); 476 sizeof(tmp_uint), &tmp_uint);
470 } 477 }
@@ -472,27 +479,27 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
472#endif 479#endif
473 } 480 }
474 481
475 if (entry->skb->nfmark) { 482 if (entskb->nfmark) {
476 tmp_uint = htonl(entry->skb->nfmark); 483 tmp_uint = htonl(entskb->nfmark);
477 NFA_PUT(skb, NFQA_MARK, sizeof(u_int32_t), &tmp_uint); 484 NFA_PUT(skb, NFQA_MARK, sizeof(u_int32_t), &tmp_uint);
478 } 485 }
479 486
480 if (entry->info->indev && entry->skb->dev 487 if (indev && entskb->dev
481 && entry->skb->dev->hard_header_parse) { 488 && entskb->dev->hard_header_parse) {
482 struct nfqnl_msg_packet_hw phw; 489 struct nfqnl_msg_packet_hw phw;
483 490
484 phw.hw_addrlen = 491 phw.hw_addrlen =
485 entry->skb->dev->hard_header_parse(entry->skb, 492 entskb->dev->hard_header_parse(entskb,
486 phw.hw_addr); 493 phw.hw_addr);
487 phw.hw_addrlen = htons(phw.hw_addrlen); 494 phw.hw_addrlen = htons(phw.hw_addrlen);
488 NFA_PUT(skb, NFQA_HWADDR, sizeof(phw), &phw); 495 NFA_PUT(skb, NFQA_HWADDR, sizeof(phw), &phw);
489 } 496 }
490 497
491 if (entry->skb->tstamp.off_sec) { 498 if (entskb->tstamp.off_sec) {
492 struct nfqnl_msg_packet_timestamp ts; 499 struct nfqnl_msg_packet_timestamp ts;
493 500
494 ts.sec = cpu_to_be64(entry->skb->tstamp.off_sec); 501 ts.sec = cpu_to_be64(entskb->tstamp.off_sec);
495 ts.usec = cpu_to_be64(entry->skb->tstamp.off_usec); 502 ts.usec = cpu_to_be64(entskb->tstamp.off_usec);
496 503
497 NFA_PUT(skb, NFQA_TIMESTAMP, sizeof(ts), &ts); 504 NFA_PUT(skb, NFQA_TIMESTAMP, sizeof(ts), &ts);
498 } 505 }
@@ -510,7 +517,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
510 nfa->nfa_type = NFQA_PAYLOAD; 517 nfa->nfa_type = NFQA_PAYLOAD;
511 nfa->nfa_len = size; 518 nfa->nfa_len = size;
512 519
513 if (skb_copy_bits(entry->skb, 0, NFA_DATA(nfa), data_len)) 520 if (skb_copy_bits(entskb, 0, NFA_DATA(nfa), data_len))
514 BUG(); 521 BUG();
515 } 522 }
516 523
@@ -667,12 +674,14 @@ nfqnl_set_mode(struct nfqnl_instance *queue,
667static int 674static int
668dev_cmp(struct nfqnl_queue_entry *entry, unsigned long ifindex) 675dev_cmp(struct nfqnl_queue_entry *entry, unsigned long ifindex)
669{ 676{
670 if (entry->info->indev) 677 struct nf_info *entinf = entry->info;
671 if (entry->info->indev->ifindex == ifindex) 678
679 if (entinf->indev)
680 if (entinf->indev->ifindex == ifindex)
672 return 1; 681 return 1;
673 682
674 if (entry->info->outdev) 683 if (entinf->outdev)
675 if (entry->info->outdev->ifindex == ifindex) 684 if (entinf->outdev->ifindex == ifindex)
676 return 1; 685 return 1;
677 686
678 return 0; 687 return 0;
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c
index a7cd2d4df757..77caf43a3109 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c
@@ -52,16 +52,13 @@ MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");
52/* 52/*
53 */ 53 */
54 54
55static dev_info_t dev_info = "snd-pdaudiocf";
56static struct snd_card *card_list[SNDRV_CARDS]; 55static struct snd_card *card_list[SNDRV_CARDS];
57static dev_link_t *dev_list;
58 56
59/* 57/*
60 * prototypes 58 * prototypes
61 */ 59 */
62static void pdacf_config(dev_link_t *link); 60static void pdacf_config(dev_link_t *link);
63static int pdacf_event(event_t event, int priority, event_callback_args_t *args); 61static void snd_pdacf_detach(struct pcmcia_device *p_dev);
64static void snd_pdacf_detach(dev_link_t *link);
65 62
66static void pdacf_release(dev_link_t *link) 63static void pdacf_release(dev_link_t *link)
67{ 64{
@@ -83,10 +80,6 @@ static int snd_pdacf_free(struct snd_pdacf *pdacf)
83 80
84 pdacf_release(link); 81 pdacf_release(link);
85 82
86 /* Break the link with Card Services */
87 if (link->handle)
88 pcmcia_deregister_client(link->handle);
89
90 card_list[pdacf->index] = NULL; 83 card_list[pdacf->index] = NULL;
91 pdacf->card = NULL; 84 pdacf->card = NULL;
92 85
@@ -103,11 +96,10 @@ static int snd_pdacf_dev_free(struct snd_device *device)
103/* 96/*
104 * snd_pdacf_attach - attach callback for cs 97 * snd_pdacf_attach - attach callback for cs
105 */ 98 */
106static dev_link_t *snd_pdacf_attach(void) 99static int snd_pdacf_attach(struct pcmcia_device *p_dev)
107{ 100{
108 client_reg_t client_reg; /* Register with cardmgr */ 101 int i;
109 dev_link_t *link; /* Info for cardmgr */ 102 dev_link_t *link; /* Info for cardmgr */
110 int i, ret;
111 struct snd_pdacf *pdacf; 103 struct snd_pdacf *pdacf;
112 struct snd_card *card; 104 struct snd_card *card;
113 static struct snd_device_ops ops = { 105 static struct snd_device_ops ops = {
@@ -122,26 +114,26 @@ static dev_link_t *snd_pdacf_attach(void)
122 } 114 }
123 if (i >= SNDRV_CARDS) { 115 if (i >= SNDRV_CARDS) {
124 snd_printk(KERN_ERR "pdacf: too many cards found\n"); 116 snd_printk(KERN_ERR "pdacf: too many cards found\n");
125 return NULL; 117 return -EINVAL;
126 } 118 }
127 if (! enable[i]) 119 if (! enable[i])
128 return NULL; /* disabled explicitly */ 120 return -ENODEV; /* disabled explicitly */
129 121
130 /* ok, create a card instance */ 122 /* ok, create a card instance */
131 card = snd_card_new(index[i], id[i], THIS_MODULE, 0); 123 card = snd_card_new(index[i], id[i], THIS_MODULE, 0);
132 if (card == NULL) { 124 if (card == NULL) {
133 snd_printk(KERN_ERR "pdacf: cannot create a card instance\n"); 125 snd_printk(KERN_ERR "pdacf: cannot create a card instance\n");
134 return NULL; 126 return -ENOMEM;
135 } 127 }
136 128
137 pdacf = snd_pdacf_create(card); 129 pdacf = snd_pdacf_create(card);
138 if (! pdacf) 130 if (! pdacf)
139 return NULL; 131 return -EIO;
140 132
141 if (snd_device_new(card, SNDRV_DEV_LOWLEVEL, pdacf, &ops) < 0) { 133 if (snd_device_new(card, SNDRV_DEV_LOWLEVEL, pdacf, &ops) < 0) {
142 kfree(pdacf); 134 kfree(pdacf);
143 snd_card_free(card); 135 snd_card_free(card);
144 return NULL; 136 return -ENODEV;
145 } 137 }
146 138
147 pdacf->index = i; 139 pdacf->index = i;
@@ -165,22 +157,12 @@ static dev_link_t *snd_pdacf_attach(void)
165 link->conf.Present = PRESENT_OPTION; 157 link->conf.Present = PRESENT_OPTION;
166 158
167 /* Chain drivers */ 159 /* Chain drivers */
168 link->next = dev_list; 160 link->next = NULL;
169 dev_list = link;
170
171 /* Register with Card Services */
172 client_reg.dev_info = &dev_info;
173 client_reg.Version = 0x0210;
174 client_reg.event_callback_args.client_data = link;
175
176 ret = pcmcia_register_client(&link->handle, &client_reg);
177 if (ret != CS_SUCCESS) {
178 cs_error(link->handle, RegisterClient, ret);
179 snd_pdacf_detach(link);
180 return NULL;
181 }
182 161
183 return link; 162 link->handle = p_dev;
163 pdacf_config(link);
164
165 return 0;
184} 166}
185 167
186 168
@@ -227,21 +209,13 @@ static int snd_pdacf_assign_resources(struct snd_pdacf *pdacf, int port, int irq
227/* 209/*
228 * snd_pdacf_detach - detach callback for cs 210 * snd_pdacf_detach - detach callback for cs
229 */ 211 */
230static void snd_pdacf_detach(dev_link_t *link) 212static void snd_pdacf_detach(struct pcmcia_device *p_dev)
231{ 213{
214 dev_link_t *link = dev_to_instance(p_dev);
232 struct snd_pdacf *chip = link->priv; 215 struct snd_pdacf *chip = link->priv;
233 216
234 snd_printdd(KERN_DEBUG "pdacf_detach called\n"); 217 snd_printdd(KERN_DEBUG "pdacf_detach called\n");
235 /* Remove the interface data from the linked list */ 218
236 {
237 dev_link_t **linkp;
238 /* Locate device structure */
239 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
240 if (*linkp == link)
241 break;
242 if (*linkp)
243 *linkp = link->next;
244 }
245 if (chip->chip_status & PDAUDIOCF_STAT_IS_CONFIGURED) 219 if (chip->chip_status & PDAUDIOCF_STAT_IS_CONFIGURED)
246 snd_pdacf_powerdown(chip); 220 snd_pdacf_powerdown(chip);
247 chip->chip_status |= PDAUDIOCF_STAT_IS_STALE; /* to be sure */ 221 chip->chip_status |= PDAUDIOCF_STAT_IS_STALE; /* to be sure */
@@ -310,62 +284,51 @@ failed:
310 pcmcia_release_irq(link->handle, &link->irq); 284 pcmcia_release_irq(link->handle, &link->irq);
311} 285}
312 286
313/* 287#ifdef CONFIG_PM
314 * event callback 288
315 */ 289static int pdacf_suspend(struct pcmcia_device *dev)
316static int pdacf_event(event_t event, int priority, event_callback_args_t *args)
317{ 290{
318 dev_link_t *link = args->client_data; 291 dev_link_t *link = dev_to_instance(dev);
319 struct snd_pdacf *chip = link->priv; 292 struct snd_pdacf *chip = link->priv;
320 293
321 switch (event) { 294 snd_printdd(KERN_DEBUG "SUSPEND\n");
322 case CS_EVENT_CARD_REMOVAL: 295 link->state |= DEV_SUSPEND;
323 snd_printdd(KERN_DEBUG "CARD_REMOVAL..\n"); 296 if (chip) {
324 link->state &= ~DEV_PRESENT; 297 snd_printdd(KERN_DEBUG "snd_pdacf_suspend calling\n");
325 if (link->state & DEV_CONFIG) { 298 snd_pdacf_suspend(chip, PMSG_SUSPEND);
326 chip->chip_status |= PDAUDIOCF_STAT_IS_STALE; 299 }
327 } 300
328 break; 301 snd_printdd(KERN_DEBUG "RESET_PHYSICAL\n");
329 case CS_EVENT_CARD_INSERTION: 302 if (link->state & DEV_CONFIG)
330 snd_printdd(KERN_DEBUG "CARD_INSERTION..\n"); 303 pcmcia_release_configuration(link->handle);
331 link->state |= DEV_PRESENT; 304
332 pdacf_config(link); 305 return 0;
333 break; 306}
334#ifdef CONFIG_PM 307
335 case CS_EVENT_PM_SUSPEND: 308static int pdacf_resume(struct pcmcia_device *dev)
336 snd_printdd(KERN_DEBUG "SUSPEND\n"); 309{
337 link->state |= DEV_SUSPEND; 310 dev_link_t *link = dev_to_instance(dev);
311 struct snd_pdacf *chip = link->priv;
312
313 snd_printdd(KERN_DEBUG "RESUME\n");
314 link->state &= ~DEV_SUSPEND;
315
316 snd_printdd(KERN_DEBUG "CARD_RESET\n");
317 if (DEV_OK(link)) {
318 snd_printdd(KERN_DEBUG "requestconfig...\n");
319 pcmcia_request_configuration(link->handle, &link->conf);
338 if (chip) { 320 if (chip) {
339 snd_printdd(KERN_DEBUG "snd_pdacf_suspend calling\n"); 321 snd_printdd(KERN_DEBUG "calling snd_pdacf_resume\n");
340 snd_pdacf_suspend(chip, PMSG_SUSPEND); 322 snd_pdacf_resume(chip);
341 }
342 /* Fall through... */
343 case CS_EVENT_RESET_PHYSICAL:
344 snd_printdd(KERN_DEBUG "RESET_PHYSICAL\n");
345 if (link->state & DEV_CONFIG)
346 pcmcia_release_configuration(link->handle);
347 break;
348 case CS_EVENT_PM_RESUME:
349 snd_printdd(KERN_DEBUG "RESUME\n");
350 link->state &= ~DEV_SUSPEND;
351 /* Fall through... */
352 case CS_EVENT_CARD_RESET:
353 snd_printdd(KERN_DEBUG "CARD_RESET\n");
354 if (DEV_OK(link)) {
355 snd_printdd(KERN_DEBUG "requestconfig...\n");
356 pcmcia_request_configuration(link->handle, &link->conf);
357 if (chip) {
358 snd_printdd(KERN_DEBUG "calling snd_pdacf_resume\n");
359 snd_pdacf_resume(chip);
360 }
361 } 323 }
362 snd_printdd(KERN_DEBUG "resume done!\n");
363 break;
364#endif
365 } 324 }
325 snd_printdd(KERN_DEBUG "resume done!\n");
326
366 return 0; 327 return 0;
367} 328}
368 329
330#endif
331
369/* 332/*
370 * Module entry points 333 * Module entry points
371 */ 334 */
@@ -380,10 +343,14 @@ static struct pcmcia_driver pdacf_cs_driver = {
380 .drv = { 343 .drv = {
381 .name = "snd-pdaudiocf", 344 .name = "snd-pdaudiocf",
382 }, 345 },
383 .attach = snd_pdacf_attach, 346 .probe = snd_pdacf_attach,
384 .event = pdacf_event, 347 .remove = snd_pdacf_detach,
385 .detach = snd_pdacf_detach,
386 .id_table = snd_pdacf_ids, 348 .id_table = snd_pdacf_ids,
349#ifdef CONFIG_PM
350 .suspend = pdacf_suspend,
351 .resume = pdacf_resume,
352#endif
353
387}; 354};
388 355
389static int __init init_pdacf(void) 356static int __init init_pdacf(void)
@@ -394,7 +361,6 @@ static int __init init_pdacf(void)
394static void __exit exit_pdacf(void) 361static void __exit exit_pdacf(void)
395{ 362{
396 pcmcia_unregister_driver(&pdacf_cs_driver); 363 pcmcia_unregister_driver(&pdacf_cs_driver);
397 BUG_ON(dev_list != NULL);
398} 364}
399 365
400module_init(init_pdacf); 366module_init(init_pdacf);
diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c
index 5bb079d17959..66900d20a42f 100644
--- a/sound/pcmcia/vx/vxpocket.c
+++ b/sound/pcmcia/vx/vxpocket.c
@@ -55,11 +55,6 @@ MODULE_PARM_DESC(ibl, "Capture IBL size for VXPocket soundcard.");
55 */ 55 */
56 56
57static unsigned int card_alloc; 57static unsigned int card_alloc;
58static dev_link_t *dev_list; /* Linked list of devices */
59static dev_info_t dev_info = "snd-vxpocket";
60
61
62static int vxpocket_event(event_t event, int priority, event_callback_args_t *args);
63 58
64 59
65/* 60/*
@@ -73,11 +68,6 @@ static void vxpocket_release(dev_link_t *link)
73 pcmcia_release_irq(link->handle, &link->irq); 68 pcmcia_release_irq(link->handle, &link->irq);
74 link->state &= ~DEV_CONFIG; 69 link->state &= ~DEV_CONFIG;
75 } 70 }
76 if (link->handle) {
77 /* Break the link with Card Services */
78 pcmcia_deregister_client(link->handle);
79 link->handle = NULL;
80 }
81} 71}
82 72
83/* 73/*
@@ -144,11 +134,9 @@ static struct snd_vx_hardware vxp440_hw = {
144 */ 134 */
145static struct snd_vxpocket *snd_vxpocket_new(struct snd_card *card, int ibl) 135static struct snd_vxpocket *snd_vxpocket_new(struct snd_card *card, int ibl)
146{ 136{
147 client_reg_t client_reg; /* Register with cardmgr */
148 dev_link_t *link; /* Info for cardmgr */ 137 dev_link_t *link; /* Info for cardmgr */
149 struct vx_core *chip; 138 struct vx_core *chip;
150 struct snd_vxpocket *vxp; 139 struct snd_vxpocket *vxp;
151 int ret;
152 static struct snd_device_ops ops = { 140 static struct snd_device_ops ops = {
153 .dev_free = snd_vxpocket_dev_free, 141 .dev_free = snd_vxpocket_dev_free,
154 }; 142 };
@@ -184,26 +172,6 @@ static struct snd_vxpocket *snd_vxpocket_new(struct snd_card *card, int ibl)
184 link->conf.ConfigIndex = 1; 172 link->conf.ConfigIndex = 1;
185 link->conf.Present = PRESENT_OPTION; 173 link->conf.Present = PRESENT_OPTION;
186 174
187 /* Register with Card Services */
188 memset(&client_reg, 0, sizeof(client_reg));
189 client_reg.dev_info = &dev_info;
190 client_reg.EventMask =
191 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL
192#ifdef CONFIG_PM
193 | CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET
194 | CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME
195#endif
196 ;
197 client_reg.event_handler = &vxpocket_event;
198 client_reg.Version = 0x0210;
199 client_reg.event_callback_args.client_data = link;
200
201 ret = pcmcia_register_client(&link->handle, &client_reg);
202 if (ret != CS_SUCCESS) {
203 cs_error(link->handle, RegisterClient, ret);
204 return NULL;
205 }
206
207 return vxp; 175 return vxp;
208} 176}
209 177
@@ -317,67 +285,55 @@ failed:
317 kfree(parse); 285 kfree(parse);
318} 286}
319 287
288#ifdef CONFIG_PM
320 289
321/* 290static int vxp_suspend(struct pcmcia_device *dev)
322 * event callback
323 */
324static int vxpocket_event(event_t event, int priority, event_callback_args_t *args)
325{ 291{
326 dev_link_t *link = args->client_data; 292 dev_link_t *link = dev_to_instance(dev);
327 struct vx_core *chip = link->priv; 293 struct vx_core *chip = link->priv;
328 294
329 switch (event) { 295 snd_printdd(KERN_DEBUG "SUSPEND\n");
330 case CS_EVENT_CARD_REMOVAL: 296 link->state |= DEV_SUSPEND;
331 snd_printdd(KERN_DEBUG "CARD_REMOVAL..\n"); 297 if (chip) {
332 link->state &= ~DEV_PRESENT; 298 snd_printdd(KERN_DEBUG "snd_vx_suspend calling\n");
333 if (link->state & DEV_CONFIG) 299 snd_vx_suspend(chip, PMSG_SUSPEND);
334 chip->chip_status |= VX_STAT_IS_STALE; 300 }
335 break; 301 snd_printdd(KERN_DEBUG "RESET_PHYSICAL\n");
336 case CS_EVENT_CARD_INSERTION: 302 if (link->state & DEV_CONFIG)
337 snd_printdd(KERN_DEBUG "CARD_INSERTION..\n"); 303 pcmcia_release_configuration(link->handle);
338 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 304
339 vxpocket_config(link); 305 return 0;
340 break; 306}
341#ifdef CONFIG_PM 307
342 case CS_EVENT_PM_SUSPEND: 308static int vxp_resume(struct pcmcia_device *dev)
343 snd_printdd(KERN_DEBUG "SUSPEND\n"); 309{
344 link->state |= DEV_SUSPEND; 310 dev_link_t *link = dev_to_instance(dev);
311 struct vx_core *chip = link->priv;
312
313 snd_printdd(KERN_DEBUG "RESUME\n");
314 link->state &= ~DEV_SUSPEND;
315
316 snd_printdd(KERN_DEBUG "CARD_RESET\n");
317 if (DEV_OK(link)) {
318 //struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip;
319 snd_printdd(KERN_DEBUG "requestconfig...\n");
320 pcmcia_request_configuration(link->handle, &link->conf);
345 if (chip) { 321 if (chip) {
346 snd_printdd(KERN_DEBUG "snd_vx_suspend calling\n"); 322 snd_printdd(KERN_DEBUG "calling snd_vx_resume\n");
347 snd_vx_suspend(chip, PMSG_SUSPEND); 323 snd_vx_resume(chip);
348 } 324 }
349 /* Fall through... */
350 case CS_EVENT_RESET_PHYSICAL:
351 snd_printdd(KERN_DEBUG "RESET_PHYSICAL\n");
352 if (link->state & DEV_CONFIG)
353 pcmcia_release_configuration(link->handle);
354 break;
355 case CS_EVENT_PM_RESUME:
356 snd_printdd(KERN_DEBUG "RESUME\n");
357 link->state &= ~DEV_SUSPEND;
358 /* Fall through... */
359 case CS_EVENT_CARD_RESET:
360 snd_printdd(KERN_DEBUG "CARD_RESET\n");
361 if (DEV_OK(link)) {
362 //struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip;
363 snd_printdd(KERN_DEBUG "requestconfig...\n");
364 pcmcia_request_configuration(link->handle, &link->conf);
365 if (chip) {
366 snd_printdd(KERN_DEBUG "calling snd_vx_resume\n");
367 snd_vx_resume(chip);
368 }
369 }
370 snd_printdd(KERN_DEBUG "resume done!\n");
371 break;
372#endif
373 } 325 }
326 snd_printdd(KERN_DEBUG "resume done!\n");
327
374 return 0; 328 return 0;
375} 329}
376 330
331#endif
332
377 333
378/* 334/*
379 */ 335 */
380static dev_link_t *vxpocket_attach(void) 336static int vxpocket_attach(struct pcmcia_device *p_dev)
381{ 337{
382 struct snd_card *card; 338 struct snd_card *card;
383 struct snd_vxpocket *vxp; 339 struct snd_vxpocket *vxp;
@@ -390,22 +346,22 @@ static dev_link_t *vxpocket_attach(void)
390 } 346 }
391 if (i >= SNDRV_CARDS) { 347 if (i >= SNDRV_CARDS) {
392 snd_printk(KERN_ERR "vxpocket: too many cards found\n"); 348 snd_printk(KERN_ERR "vxpocket: too many cards found\n");
393 return NULL; 349 return -EINVAL;
394 } 350 }
395 if (! enable[i]) 351 if (! enable[i])
396 return NULL; /* disabled explicitly */ 352 return -ENODEV; /* disabled explicitly */
397 353
398 /* ok, create a card instance */ 354 /* ok, create a card instance */
399 card = snd_card_new(index[i], id[i], THIS_MODULE, 0); 355 card = snd_card_new(index[i], id[i], THIS_MODULE, 0);
400 if (card == NULL) { 356 if (card == NULL) {
401 snd_printk(KERN_ERR "vxpocket: cannot create a card instance\n"); 357 snd_printk(KERN_ERR "vxpocket: cannot create a card instance\n");
402 return NULL; 358 return -ENOMEM;
403 } 359 }
404 360
405 vxp = snd_vxpocket_new(card, ibl[i]); 361 vxp = snd_vxpocket_new(card, ibl[i]);
406 if (! vxp) { 362 if (! vxp) {
407 snd_card_free(card); 363 snd_card_free(card);
408 return NULL; 364 return -ENODEV;
409 } 365 }
410 card->private_data = vxp; 366 card->private_data = vxp;
411 367
@@ -413,17 +369,21 @@ static dev_link_t *vxpocket_attach(void)
413 card_alloc |= 1 << i; 369 card_alloc |= 1 << i;
414 370
415 /* Chain drivers */ 371 /* Chain drivers */
416 vxp->link.next = dev_list; 372 vxp->link.next = NULL;
417 dev_list = &vxp->link; 373
374 vxp->link.handle = p_dev;
375 vxp->link.state |= DEV_PRESENT | DEV_CONFIG_PENDING;
376 p_dev->instance = &vxp->link;
377 vxpocket_config(&vxp->link);
418 378
419 return &vxp->link; 379 return 0;
420} 380}
421 381
422static void vxpocket_detach(dev_link_t *link) 382static void vxpocket_detach(struct pcmcia_device *p_dev)
423{ 383{
384 dev_link_t *link = dev_to_instance(p_dev);
424 struct snd_vxpocket *vxp; 385 struct snd_vxpocket *vxp;
425 struct vx_core *chip; 386 struct vx_core *chip;
426 dev_link_t **linkp;
427 387
428 if (! link) 388 if (! link)
429 return; 389 return;
@@ -432,13 +392,6 @@ static void vxpocket_detach(dev_link_t *link)
432 chip = (struct vx_core *)vxp; 392 chip = (struct vx_core *)vxp;
433 card_alloc &= ~(1 << vxp->index); 393 card_alloc &= ~(1 << vxp->index);
434 394
435 /* Remove the interface data from the linked list */
436 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
437 if (*linkp == link) {
438 *linkp = link->next;
439 break;
440 }
441
442 chip->chip_status |= VX_STAT_IS_STALE; /* to be sure */ 395 chip->chip_status |= VX_STAT_IS_STALE; /* to be sure */
443 snd_card_disconnect(chip->card); 396 snd_card_disconnect(chip->card);
444 vxpocket_release(link); 397 vxpocket_release(link);
@@ -460,10 +413,13 @@ static struct pcmcia_driver vxp_cs_driver = {
460 .drv = { 413 .drv = {
461 .name = "snd-vxpocket", 414 .name = "snd-vxpocket",
462 }, 415 },
463 .attach = vxpocket_attach, 416 .probe = vxpocket_attach,
464 .detach = vxpocket_detach, 417 .remove = vxpocket_detach,
465 .event = vxpocket_event,
466 .id_table = vxp_ids, 418 .id_table = vxp_ids,
419#ifdef CONFIG_PM
420 .suspend = vxp_suspend,
421 .resume = vxp_resume,
422#endif
467}; 423};
468 424
469static int __init init_vxpocket(void) 425static int __init init_vxpocket(void)
@@ -474,7 +430,6 @@ static int __init init_vxpocket(void)
474static void __exit exit_vxpocket(void) 430static void __exit exit_vxpocket(void)
475{ 431{
476 pcmcia_unregister_driver(&vxp_cs_driver); 432 pcmcia_unregister_driver(&vxp_cs_driver);
477 BUG_ON(dev_list != NULL);
478} 433}
479 434
480module_init(init_vxpocket); 435module_init(init_vxpocket);