0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023 #ifdef __IN_PCMCIA_PACKAGE__
0024 #include <pcmcia/k_compat.h>
0025 #endif
0026 #include <linux/kernel.h>
0027 #include <linux/module.h>
0028 #include <linux/ptrace.h>
0029 #include <linux/slab.h>
0030 #include <linux/string.h>
0031 #include <linux/timer.h>
0032 #include <linux/netdevice.h>
0033
0034 #include <pcmcia/cistpl.h>
0035 #include <pcmcia/cisreg.h>
0036 #include <pcmcia/ds.h>
0037
0038 #include <linux/io.h>
0039
0040 #include "airo.h"
0041
0042
0043
0044
0045 MODULE_AUTHOR("Benjamin Reed");
0046 MODULE_DESCRIPTION("Support for Cisco/Aironet 802.11 wireless ethernet "
0047 "cards. This is the module that links the PCMCIA card "
0048 "with the airo module.");
0049 MODULE_LICENSE("Dual BSD/GPL");
0050
0051
0052
0053 static int airo_config(struct pcmcia_device *link);
0054 static void airo_release(struct pcmcia_device *link);
0055
0056 static void airo_detach(struct pcmcia_device *p_dev);
0057
0058 struct local_info {
0059 struct net_device *eth_dev;
0060 };
0061
0062 static int airo_probe(struct pcmcia_device *p_dev)
0063 {
0064 struct local_info *local;
0065
0066 dev_dbg(&p_dev->dev, "airo_attach()\n");
0067
0068
0069 local = kzalloc(sizeof(*local), GFP_KERNEL);
0070 if (!local)
0071 return -ENOMEM;
0072
0073 p_dev->priv = local;
0074
0075 return airo_config(p_dev);
0076 }
0077
0078 static void airo_detach(struct pcmcia_device *link)
0079 {
0080 dev_dbg(&link->dev, "airo_detach\n");
0081
0082 airo_release(link);
0083
0084 if (((struct local_info *)link->priv)->eth_dev) {
0085 stop_airo_card(((struct local_info *)link->priv)->eth_dev,
0086 0);
0087 }
0088 ((struct local_info *)link->priv)->eth_dev = NULL;
0089
0090 kfree(link->priv);
0091 }
0092
0093 static int airo_cs_config_check(struct pcmcia_device *p_dev, void *priv_data)
0094 {
0095 if (p_dev->config_index == 0)
0096 return -EINVAL;
0097
0098 return pcmcia_request_io(p_dev);
0099 }
0100
0101
0102 static int airo_config(struct pcmcia_device *link)
0103 {
0104 int ret;
0105
0106 dev_dbg(&link->dev, "airo_config\n");
0107
0108 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_VPP |
0109 CONF_AUTO_AUDIO | CONF_AUTO_SET_IO;
0110
0111 ret = pcmcia_loop_config(link, airo_cs_config_check, NULL);
0112 if (ret)
0113 goto failed;
0114
0115 if (!link->irq)
0116 goto failed;
0117
0118 ret = pcmcia_enable_device(link);
0119 if (ret)
0120 goto failed;
0121 ((struct local_info *)link->priv)->eth_dev =
0122 init_airo_card(link->irq,
0123 link->resource[0]->start, 1, &link->dev);
0124 if (!((struct local_info *)link->priv)->eth_dev)
0125 goto failed;
0126
0127 return 0;
0128
0129 failed:
0130 airo_release(link);
0131 return -ENODEV;
0132 }
0133
0134 static void airo_release(struct pcmcia_device *link)
0135 {
0136 dev_dbg(&link->dev, "airo_release\n");
0137 pcmcia_disable_device(link);
0138 }
0139
0140 static int airo_suspend(struct pcmcia_device *link)
0141 {
0142 struct local_info *local = link->priv;
0143
0144 netif_device_detach(local->eth_dev);
0145
0146 return 0;
0147 }
0148
0149 static int airo_resume(struct pcmcia_device *link)
0150 {
0151 struct local_info *local = link->priv;
0152
0153 if (link->open) {
0154 reset_airo_card(local->eth_dev);
0155 netif_device_attach(local->eth_dev);
0156 }
0157
0158 return 0;
0159 }
0160
0161 static const struct pcmcia_device_id airo_ids[] = {
0162 PCMCIA_DEVICE_MANF_CARD(0x015f, 0x000a),
0163 PCMCIA_DEVICE_MANF_CARD(0x015f, 0x0005),
0164 PCMCIA_DEVICE_MANF_CARD(0x015f, 0x0007),
0165 PCMCIA_DEVICE_MANF_CARD(0x0105, 0x0007),
0166 PCMCIA_DEVICE_NULL,
0167 };
0168 MODULE_DEVICE_TABLE(pcmcia, airo_ids);
0169
0170 static struct pcmcia_driver airo_driver = {
0171 .owner = THIS_MODULE,
0172 .name = "airo_cs",
0173 .probe = airo_probe,
0174 .remove = airo_detach,
0175 .id_table = airo_ids,
0176 .suspend = airo_suspend,
0177 .resume = airo_resume,
0178 };
0179 module_pcmcia_driver(airo_driver);
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218