0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #include "hardware.h"
0020 #include "network.h"
0021 #include "main.h"
0022 #include "tty.h"
0023
0024 #include <linux/delay.h>
0025 #include <linux/init.h>
0026 #include <linux/io.h>
0027 #include <linux/kernel.h>
0028 #include <linux/module.h>
0029 #include <linux/sched.h>
0030 #include <linux/slab.h>
0031
0032 #include <pcmcia/cisreg.h>
0033 #include <pcmcia/device_id.h>
0034 #include <pcmcia/ss.h>
0035 #include <pcmcia/ds.h>
0036
0037 static const struct pcmcia_device_id ipw_ids[] = {
0038 PCMCIA_DEVICE_MANF_CARD(0x02f2, 0x0100),
0039 PCMCIA_DEVICE_MANF_CARD(0x02f2, 0x0200),
0040 PCMCIA_DEVICE_NULL
0041 };
0042 MODULE_DEVICE_TABLE(pcmcia, ipw_ids);
0043
0044 static void ipwireless_detach(struct pcmcia_device *link);
0045
0046
0047
0048
0049
0050 int ipwireless_debug;
0051 int ipwireless_loopback;
0052 int ipwireless_out_queue = 10;
0053
0054 module_param_named(debug, ipwireless_debug, int, 0);
0055 module_param_named(loopback, ipwireless_loopback, int, 0);
0056 module_param_named(out_queue, ipwireless_out_queue, int, 0);
0057 MODULE_PARM_DESC(debug, "switch on debug messages [0]");
0058 MODULE_PARM_DESC(loopback,
0059 "debug: enable ras_raw channel [0]");
0060 MODULE_PARM_DESC(out_queue, "debug: set size of outgoing PPP queue [10]");
0061
0062
0063 static void signalled_reboot_work(struct work_struct *work_reboot)
0064 {
0065 struct ipw_dev *ipw = container_of(work_reboot, struct ipw_dev,
0066 work_reboot);
0067 struct pcmcia_device *link = ipw->link;
0068 pcmcia_reset_card(link->socket);
0069 }
0070
0071 static void signalled_reboot_callback(void *callback_data)
0072 {
0073 struct ipw_dev *ipw = (struct ipw_dev *) callback_data;
0074
0075
0076 schedule_work(&ipw->work_reboot);
0077 }
0078
0079 static int ipwireless_probe(struct pcmcia_device *p_dev, void *priv_data)
0080 {
0081 struct ipw_dev *ipw = priv_data;
0082 int ret;
0083
0084 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
0085 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
0086
0087
0088
0089 p_dev->config_index |= 0x44;
0090 p_dev->io_lines = 16;
0091 ret = pcmcia_request_io(p_dev);
0092 if (ret)
0093 return ret;
0094
0095 if (!request_region(p_dev->resource[0]->start,
0096 resource_size(p_dev->resource[0]),
0097 IPWIRELESS_PCCARD_NAME)) {
0098 ret = -EBUSY;
0099 goto exit;
0100 }
0101
0102 p_dev->resource[2]->flags |=
0103 WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM | WIN_ENABLE;
0104
0105 ret = pcmcia_request_window(p_dev, p_dev->resource[2], 0);
0106 if (ret != 0)
0107 goto exit1;
0108
0109 ret = pcmcia_map_mem_page(p_dev, p_dev->resource[2], p_dev->card_addr);
0110 if (ret != 0)
0111 goto exit1;
0112
0113 ipw->is_v2_card = resource_size(p_dev->resource[2]) == 0x100;
0114
0115 ipw->common_memory = ioremap(p_dev->resource[2]->start,
0116 resource_size(p_dev->resource[2]));
0117 if (!ipw->common_memory) {
0118 ret = -ENOMEM;
0119 goto exit1;
0120 }
0121 if (!request_mem_region(p_dev->resource[2]->start,
0122 resource_size(p_dev->resource[2]),
0123 IPWIRELESS_PCCARD_NAME)) {
0124 ret = -EBUSY;
0125 goto exit2;
0126 }
0127
0128 p_dev->resource[3]->flags |= WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_AM |
0129 WIN_ENABLE;
0130 p_dev->resource[3]->end = 0;
0131 ret = pcmcia_request_window(p_dev, p_dev->resource[3], 0);
0132 if (ret != 0)
0133 goto exit3;
0134
0135 ret = pcmcia_map_mem_page(p_dev, p_dev->resource[3], 0);
0136 if (ret != 0)
0137 goto exit3;
0138
0139 ipw->attr_memory = ioremap(p_dev->resource[3]->start,
0140 resource_size(p_dev->resource[3]));
0141 if (!ipw->attr_memory) {
0142 ret = -ENOMEM;
0143 goto exit3;
0144 }
0145 if (!request_mem_region(p_dev->resource[3]->start,
0146 resource_size(p_dev->resource[3]),
0147 IPWIRELESS_PCCARD_NAME)) {
0148 ret = -EBUSY;
0149 goto exit4;
0150 }
0151
0152 return 0;
0153
0154 exit4:
0155 iounmap(ipw->attr_memory);
0156 exit3:
0157 release_mem_region(p_dev->resource[2]->start,
0158 resource_size(p_dev->resource[2]));
0159 exit2:
0160 iounmap(ipw->common_memory);
0161 exit1:
0162 release_region(p_dev->resource[0]->start,
0163 resource_size(p_dev->resource[0]));
0164 exit:
0165 pcmcia_disable_device(p_dev);
0166 return ret;
0167 }
0168
0169 static int config_ipwireless(struct ipw_dev *ipw)
0170 {
0171 struct pcmcia_device *link = ipw->link;
0172 int ret = 0;
0173
0174 ipw->is_v2_card = 0;
0175 link->config_flags |= CONF_AUTO_SET_IO | CONF_AUTO_SET_IOMEM |
0176 CONF_ENABLE_IRQ;
0177
0178 ret = pcmcia_loop_config(link, ipwireless_probe, ipw);
0179 if (ret != 0)
0180 return ret;
0181
0182 INIT_WORK(&ipw->work_reboot, signalled_reboot_work);
0183
0184 ipwireless_init_hardware_v1(ipw->hardware, link->resource[0]->start,
0185 ipw->attr_memory, ipw->common_memory,
0186 ipw->is_v2_card, signalled_reboot_callback,
0187 ipw);
0188
0189 ret = pcmcia_request_irq(link, ipwireless_interrupt);
0190 if (ret != 0)
0191 goto exit;
0192
0193 printk(KERN_INFO IPWIRELESS_PCCARD_NAME ": Card type %s\n",
0194 ipw->is_v2_card ? "V2/V3" : "V1");
0195 printk(KERN_INFO IPWIRELESS_PCCARD_NAME
0196 ": I/O ports %pR, irq %d\n", link->resource[0],
0197 (unsigned int) link->irq);
0198 if (ipw->attr_memory && ipw->common_memory)
0199 printk(KERN_INFO IPWIRELESS_PCCARD_NAME
0200 ": attr memory %pR, common memory %pR\n",
0201 link->resource[3],
0202 link->resource[2]);
0203
0204 ipw->network = ipwireless_network_create(ipw->hardware);
0205 if (!ipw->network)
0206 goto exit;
0207
0208 ipw->tty = ipwireless_tty_create(ipw->hardware, ipw->network);
0209 if (!ipw->tty)
0210 goto exit;
0211
0212 ipwireless_init_hardware_v2_v3(ipw->hardware);
0213
0214
0215
0216
0217
0218 ret = pcmcia_enable_device(link);
0219 if (ret != 0)
0220 goto exit;
0221
0222 return 0;
0223
0224 exit:
0225 if (ipw->common_memory) {
0226 release_mem_region(link->resource[2]->start,
0227 resource_size(link->resource[2]));
0228 iounmap(ipw->common_memory);
0229 }
0230 if (ipw->attr_memory) {
0231 release_mem_region(link->resource[3]->start,
0232 resource_size(link->resource[3]));
0233 iounmap(ipw->attr_memory);
0234 }
0235 pcmcia_disable_device(link);
0236 return -1;
0237 }
0238
0239 static void release_ipwireless(struct ipw_dev *ipw)
0240 {
0241 release_region(ipw->link->resource[0]->start,
0242 resource_size(ipw->link->resource[0]));
0243 if (ipw->common_memory) {
0244 release_mem_region(ipw->link->resource[2]->start,
0245 resource_size(ipw->link->resource[2]));
0246 iounmap(ipw->common_memory);
0247 }
0248 if (ipw->attr_memory) {
0249 release_mem_region(ipw->link->resource[3]->start,
0250 resource_size(ipw->link->resource[3]));
0251 iounmap(ipw->attr_memory);
0252 }
0253 pcmcia_disable_device(ipw->link);
0254 }
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265 static int ipwireless_attach(struct pcmcia_device *link)
0266 {
0267 struct ipw_dev *ipw;
0268 int ret;
0269
0270 ipw = kzalloc(sizeof(struct ipw_dev), GFP_KERNEL);
0271 if (!ipw)
0272 return -ENOMEM;
0273
0274 ipw->link = link;
0275 link->priv = ipw;
0276
0277 ipw->hardware = ipwireless_hardware_create();
0278 if (!ipw->hardware) {
0279 kfree(ipw);
0280 return -ENOMEM;
0281 }
0282
0283
0284 ret = config_ipwireless(ipw);
0285
0286 if (ret != 0) {
0287 ipwireless_detach(link);
0288 return ret;
0289 }
0290
0291 return 0;
0292 }
0293
0294
0295
0296
0297
0298
0299
0300 static void ipwireless_detach(struct pcmcia_device *link)
0301 {
0302 struct ipw_dev *ipw = link->priv;
0303
0304 release_ipwireless(ipw);
0305
0306 if (ipw->tty != NULL)
0307 ipwireless_tty_free(ipw->tty);
0308 if (ipw->network != NULL)
0309 ipwireless_network_free(ipw->network);
0310 if (ipw->hardware != NULL)
0311 ipwireless_hardware_free(ipw->hardware);
0312 kfree(ipw);
0313 }
0314
0315 static struct pcmcia_driver me = {
0316 .owner = THIS_MODULE,
0317 .probe = ipwireless_attach,
0318 .remove = ipwireless_detach,
0319 .name = IPWIRELESS_PCCARD_NAME,
0320 .id_table = ipw_ids
0321 };
0322
0323
0324
0325
0326
0327 static int __init init_ipwireless(void)
0328 {
0329 int ret;
0330
0331 ret = ipwireless_tty_init();
0332 if (ret != 0)
0333 return ret;
0334
0335 ret = pcmcia_register_driver(&me);
0336 if (ret != 0)
0337 ipwireless_tty_release();
0338
0339 return ret;
0340 }
0341
0342
0343
0344
0345 static void __exit exit_ipwireless(void)
0346 {
0347 pcmcia_unregister_driver(&me);
0348 ipwireless_tty_release();
0349 }
0350
0351 module_init(init_ipwireless);
0352 module_exit(exit_ipwireless);
0353
0354 MODULE_AUTHOR(IPWIRELESS_PCMCIA_AUTHOR);
0355 MODULE_DESCRIPTION(IPWIRELESS_PCCARD_NAME " " IPWIRELESS_PCMCIA_VERSION);
0356 MODULE_LICENSE("GPL");