1 /* $Id: avm_cs.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
2 *
3 * A PCMCIA client driver for AVM B1/M1/M2
4 *
5 * Copyright 1999 by Carsten Paeth <calle@calle.de>
6 *
7 * This software may be used and distributed according to the terms
8 * of the GNU General Public License, incorporated herein by reference.
9 *
10 */
11
12 #include <linux/module.h>
13 #include <linux/kernel.h>
14 #include <linux/init.h>
15 #include <linux/sched.h>
16 #include <linux/ptrace.h>
17 #include <linux/slab.h>
18 #include <linux/string.h>
19 #include <linux/timer.h>
20 #include <linux/tty.h>
21 #include <linux/serial.h>
22 #include <linux/major.h>
23 #include <asm/io.h>
24 #include <asm/system.h>
25
26 #include <pcmcia/version.h>
27 #include <pcmcia/cs_types.h>
28 #include <pcmcia/cs.h>
29 #include <pcmcia/cistpl.h>
30 #include <pcmcia/ciscode.h>
31 #include <pcmcia/ds.h>
32 #include <pcmcia/cisreg.h>
33
34 #include <linux/skbuff.h>
35 #include <linux/capi.h>
36 #include <linux/b1lli.h>
37 #include <linux/b1pcmcia.h>
38
39 /*====================================================================*/
40
41 MODULE_DESCRIPTION("CAPI4Linux: PCMCIA client driver for AVM B1/M1/M2");
42 MODULE_AUTHOR("Carsten Paeth");
43 MODULE_LICENSE("GPL");
44
45 /*====================================================================*/
46
47 /* Parameters that can be set with 'insmod' */
48
49 /* This means pick from 15, 12, 11, 10, 9, 7, 5, 4, and 3 */
50 static int default_irq_list[10] = { 15, 12, 11, 10, 9, 7, 5, 4, 3, -1 };
51 static int irq_list[10] = { -1 };
52
53 MODULE_PARM(irq_list, "1-10i");
54
55 /*====================================================================*/
56
57 /*
58 The event() function is this driver's Card Services event handler.
59 It will be called by Card Services when an appropriate card status
60 event is received. The config() and release() entry points are
61 used to configure or release a socket, in response to card insertion
62 and ejection events. They are invoked from the skeleton event
63 handler.
64 */
65
66 static void avmcs_config(dev_link_t *link);
67 static void avmcs_release(u_long arg);
68 static int avmcs_event(event_t event, int priority,
69 event_callback_args_t *args);
70
71 /*
72 The attach() and detach() entry points are used to create and destroy
73 "instances" of the driver, where each instance represents everything
74 needed to manage one actual PCMCIA card.
75 */
76
77 static dev_link_t *avmcs_attach(void);
78 static void avmcs_detach(dev_link_t *);
79
80 /*
81 The dev_info variable is the "key" that is used to match up this
82 device driver with appropriate cards, through the card configuration
83 database.
84 */
85
86 static dev_info_t dev_info = "avm_cs";
87
88 /*
89 A linked list of "instances" of the skeleton device. Each actual
90 PCMCIA card corresponds to one device instance, and is described
91 by one dev_link_t structure (defined in ds.h).
92
93 You may not want to use a linked list for this -- for example, the
94 memory card driver uses an array of dev_link_t pointers, where minor
95 device numbers are used to derive the corresponding array index.
96 */
97
98 static dev_link_t *dev_list = NULL;
99
100 /*
101 A dev_link_t structure has fields for most things that are needed
102 to keep track of a socket, but there will usually be some device
103 specific information that also needs to be kept track of. The
104 'priv' pointer in a dev_link_t structure can be used to point to
105 a device-specific private data structure, like this.
106
107 A driver needs to provide a dev_node_t structure for each device
108 on a card. In some cases, there is only one device per card (for
109 example, ethernet cards, modems). In other cases, there may be
110 many actual or logical devices (SCSI adapters, memory cards with
111 multiple partitions). The dev_node_t structures need to be kept
112 in a linked list starting at the 'dev' field of a dev_link_t
113 structure. We allocate them in the card's private data structure,
114 because they generally can't be allocated dynamically.
115 */
116
117 typedef struct local_info_t {
118 dev_node_t node;
119 } local_info_t;
120
121 /*====================================================================*/
122
cs_error(client_handle_t handle,int func,int ret)123 static void cs_error(client_handle_t handle, int func, int ret)
124 {
125 error_info_t err = { func, ret };
126 CardServices(ReportError, handle, &err);
127 }
128
129 /*======================================================================
130
131 avmcs_attach() creates an "instance" of the driver, allocating
132 local data structures for one device. The device is registered
133 with Card Services.
134
135 The dev_link structure is initialized, but we don't actually
136 configure the card at this point -- we wait until we receive a
137 card insertion event.
138
139 ======================================================================*/
140
avmcs_attach(void)141 static dev_link_t *avmcs_attach(void)
142 {
143 client_reg_t client_reg;
144 dev_link_t *link;
145 local_info_t *local;
146 int ret, i;
147
148 /* Initialize the dev_link_t structure */
149 link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
150 if (!link)
151 return NULL;
152 memset(link, 0, sizeof(struct dev_link_t));
153 link->release.function = &avmcs_release;
154 link->release.data = (u_long)link;
155
156 /* The io structure describes IO port mapping */
157 link->io.NumPorts1 = 16;
158 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
159 link->io.NumPorts2 = 0;
160
161 /* Interrupt setup */
162 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
163 link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
164
165 link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
166 if (irq_list[0] != -1) {
167 for (i = 0; i < 10 && irq_list[i] > 0; i++)
168 link->irq.IRQInfo2 |= 1 << irq_list[i];
169 } else {
170 for (i = 0; i < 10 && default_irq_list[i] > 0; i++)
171 link->irq.IRQInfo2 |= 1 << default_irq_list[i];
172 }
173
174 /* General socket configuration */
175 link->conf.Attributes = CONF_ENABLE_IRQ;
176 link->conf.Vcc = 50;
177 link->conf.IntType = INT_MEMORY_AND_IO;
178 link->conf.ConfigIndex = 1;
179 link->conf.Present = PRESENT_OPTION;
180
181 /* Allocate space for private device-specific data */
182 local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
183 if (!local)
184 return NULL;
185 memset(local, 0, sizeof(local_info_t));
186 link->priv = local;
187
188 /* Register with Card Services */
189 link->next = dev_list;
190 dev_list = link;
191 client_reg.dev_info = &dev_info;
192 client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
193 client_reg.EventMask =
194 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
195 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
196 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
197 client_reg.event_handler = &avmcs_event;
198 client_reg.Version = 0x0210;
199 client_reg.event_callback_args.client_data = link;
200 ret = CardServices(RegisterClient, &link->handle, &client_reg);
201 if (ret != 0) {
202 cs_error(link->handle, RegisterClient, ret);
203 avmcs_detach(link);
204 return NULL;
205 }
206
207 return link;
208 } /* avmcs_attach */
209
210 /*======================================================================
211
212 This deletes a driver "instance". The device is de-registered
213 with Card Services. If it has been released, all local data
214 structures are freed. Otherwise, the structures will be freed
215 when the device is released.
216
217 ======================================================================*/
218
avmcs_detach(dev_link_t * link)219 static void avmcs_detach(dev_link_t *link)
220 {
221 dev_link_t **linkp;
222
223 /* Locate device structure */
224 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
225 if (*linkp == link) break;
226 if (*linkp == NULL)
227 return;
228
229 /*
230 If the device is currently configured and active, we won't
231 actually delete it yet. Instead, it is marked so that when
232 the release() function is called, that will trigger a proper
233 detach().
234 */
235 if (link->state & DEV_CONFIG) {
236 link->state |= DEV_STALE_LINK;
237 return;
238 }
239
240 /* Break the link with Card Services */
241 if (link->handle)
242 CardServices(DeregisterClient, link->handle);
243
244 /* Unlink device structure, free pieces */
245 *linkp = link->next;
246 if (link->priv) {
247 kfree(link->priv);
248 }
249 kfree(link);
250
251 } /* avmcs_detach */
252
253 /*======================================================================
254
255 avmcs_config() is scheduled to run after a CARD_INSERTION event
256 is received, to configure the PCMCIA socket, and to make the
257 ethernet device available to the system.
258
259 ======================================================================*/
260
get_tuple(int fn,client_handle_t handle,tuple_t * tuple,cisparse_t * parse)261 static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple,
262 cisparse_t *parse)
263 {
264 int i;
265 i = CardServices(fn, handle, tuple);
266 if (i != CS_SUCCESS) return i;
267 i = CardServices(GetTupleData, handle, tuple);
268 if (i != CS_SUCCESS) return i;
269 return CardServices(ParseTuple, handle, tuple, parse);
270 }
271
272 #define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
273 #define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
274
avmcs_config(dev_link_t * link)275 static void avmcs_config(dev_link_t *link)
276 {
277 client_handle_t handle;
278 tuple_t tuple;
279 cisparse_t parse;
280 cistpl_cftable_entry_t *cf = &parse.cftable_entry;
281 local_info_t *dev;
282 int i;
283 u_char buf[64];
284 char devname[128];
285 int cardtype;
286 int (*addcard)(unsigned int port, unsigned irq);
287
288 handle = link->handle;
289 dev = link->priv;
290
291 /*
292 This reads the card's CONFIG tuple to find its configuration
293 registers.
294 */
295 do {
296 tuple.DesiredTuple = CISTPL_CONFIG;
297 i = CardServices(GetFirstTuple, handle, &tuple);
298 if (i != CS_SUCCESS) break;
299 tuple.TupleData = buf;
300 tuple.TupleDataMax = 64;
301 tuple.TupleOffset = 0;
302 i = CardServices(GetTupleData, handle, &tuple);
303 if (i != CS_SUCCESS) break;
304 i = CardServices(ParseTuple, handle, &tuple, &parse);
305 if (i != CS_SUCCESS) break;
306 link->conf.ConfigBase = parse.config.base;
307 } while (0);
308 if (i != CS_SUCCESS) {
309 cs_error(link->handle, ParseTuple, i);
310 link->state &= ~DEV_CONFIG_PENDING;
311 return;
312 }
313
314 /* Configure card */
315 link->state |= DEV_CONFIG;
316
317 do {
318
319 tuple.Attributes = 0;
320 tuple.TupleData = buf;
321 tuple.TupleDataMax = 254;
322 tuple.TupleOffset = 0;
323 tuple.DesiredTuple = CISTPL_VERS_1;
324
325 devname[0] = 0;
326 if( !first_tuple(handle, &tuple, &parse) && parse.version_1.ns > 1 ) {
327 strncpy(devname,parse.version_1.str + parse.version_1.ofs[1],
328 sizeof(devname));
329 }
330 /*
331 * find IO port
332 */
333 tuple.TupleData = (cisdata_t *)buf;
334 tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
335 tuple.Attributes = 0;
336 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
337 i = first_tuple(handle, &tuple, &parse);
338 while (i == CS_SUCCESS) {
339 if (cf->io.nwin > 0) {
340 link->conf.ConfigIndex = cf->index;
341 link->io.BasePort1 = cf->io.win[0].base;
342 link->io.NumPorts1 = cf->io.win[0].len;
343 link->io.NumPorts2 = 0;
344 printk(KERN_INFO "avm_cs: testing i/o %#x-%#x\n",
345 link->io.BasePort1,
346 link->io.BasePort1+link->io.NumPorts1-1);
347 i = CardServices(RequestIO, link->handle, &link->io);
348 if (i == CS_SUCCESS) goto found_port;
349 }
350 i = next_tuple(handle, &tuple, &parse);
351 }
352
353 found_port:
354 if (i != CS_SUCCESS) {
355 cs_error(link->handle, RequestIO, i);
356 break;
357 }
358
359 /*
360 * allocate an interrupt line
361 */
362 i = CardServices(RequestIRQ, link->handle, &link->irq);
363 if (i != CS_SUCCESS) {
364 cs_error(link->handle, RequestIRQ, i);
365 CardServices(ReleaseIO, link->handle, &link->io);
366 break;
367 }
368
369 /*
370 * configure the PCMCIA socket
371 */
372 i = CardServices(RequestConfiguration, link->handle, &link->conf);
373 if (i != CS_SUCCESS) {
374 cs_error(link->handle, RequestConfiguration, i);
375 CardServices(ReleaseIO, link->handle, &link->io);
376 CardServices(ReleaseIRQ, link->handle, &link->irq);
377 break;
378 }
379
380 } while (0);
381
382 /* At this point, the dev_node_t structure(s) should be
383 initialized and arranged in a linked list at link->dev. */
384
385 if (devname[0]) {
386 char *s = strrchr(devname, ' ');
387 if (!s)
388 s = devname;
389 else s++;
390 strcpy(dev->node.dev_name, s);
391 if (strcmp("M1", s) == 0) {
392 cardtype = AVM_CARDTYPE_M1;
393 } else if (strcmp("M2", s) == 0) {
394 cardtype = AVM_CARDTYPE_M2;
395 } else {
396 cardtype = AVM_CARDTYPE_B1;
397 }
398 } else {
399 strcpy(dev->node.dev_name, "b1");
400 cardtype = AVM_CARDTYPE_B1;
401 }
402
403 dev->node.major = 64;
404 dev->node.minor = 0;
405 link->dev = &dev->node;
406
407 link->state &= ~DEV_CONFIG_PENDING;
408 /* If any step failed, release any partially configured state */
409 if (i != 0) {
410 avmcs_release((u_long)link);
411 return;
412 }
413
414
415 switch (cardtype) {
416 case AVM_CARDTYPE_M1: addcard = b1pcmcia_addcard_m1; break;
417 case AVM_CARDTYPE_M2: addcard = b1pcmcia_addcard_m2; break;
418 default:
419 case AVM_CARDTYPE_B1: addcard = b1pcmcia_addcard_b1; break;
420 }
421 if ((i = (*addcard)(link->io.BasePort1, link->irq.AssignedIRQ)) < 0) {
422 printk(KERN_ERR "avm_cs: failed to add AVM-%s-Controller at i/o %#x, irq %d\n",
423 dev->node.dev_name, link->io.BasePort1, link->irq.AssignedIRQ);
424 avmcs_release((u_long)link);
425 return;
426 }
427 dev->node.minor = i;
428
429 } /* avmcs_config */
430
431 /*======================================================================
432
433 After a card is removed, avmcs_release() will unregister the net
434 device, and release the PCMCIA configuration. If the device is
435 still open, this will be postponed until it is closed.
436
437 ======================================================================*/
438
avmcs_release(u_long arg)439 static void avmcs_release(u_long arg)
440 {
441 dev_link_t *link = (dev_link_t *)arg;
442
443 /*
444 If the device is currently in use, we won't release until it
445 is actually closed.
446 */
447 if (link->open) {
448 link->state |= DEV_STALE_CONFIG;
449 return;
450 }
451
452 b1pcmcia_delcard(link->io.BasePort1, link->irq.AssignedIRQ);
453
454 /* Unlink the device chain */
455 link->dev = NULL;
456
457 /* Don't bother checking to see if these succeed or not */
458 CardServices(ReleaseConfiguration, link->handle);
459 CardServices(ReleaseIO, link->handle, &link->io);
460 CardServices(ReleaseIRQ, link->handle, &link->irq);
461 link->state &= ~DEV_CONFIG;
462
463 if (link->state & DEV_STALE_LINK)
464 avmcs_detach(link);
465
466 } /* avmcs_release */
467
468 /*======================================================================
469
470 The card status event handler. Mostly, this schedules other
471 stuff to run after an event is received. A CARD_REMOVAL event
472 also sets some flags to discourage the net drivers from trying
473 to talk to the card any more.
474
475 When a CARD_REMOVAL event is received, we immediately set a flag
476 to block future accesses to this device. All the functions that
477 actually access the device should check this flag to make sure
478 the card is still present.
479
480 ======================================================================*/
481
avmcs_event(event_t event,int priority,event_callback_args_t * args)482 static int avmcs_event(event_t event, int priority,
483 event_callback_args_t *args)
484 {
485 dev_link_t *link = args->client_data;
486
487 switch (event) {
488 case CS_EVENT_CARD_REMOVAL:
489 link->state &= ~DEV_PRESENT;
490 if (link->state & DEV_CONFIG) {
491 link->release.expires = jiffies + (HZ/20);
492 add_timer(&link->release);
493 }
494 break;
495 case CS_EVENT_CARD_INSERTION:
496 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
497 avmcs_config(link);
498 break;
499 case CS_EVENT_PM_SUSPEND:
500 link->state |= DEV_SUSPEND;
501 /* Fall through... */
502 case CS_EVENT_RESET_PHYSICAL:
503 if (link->state & DEV_CONFIG)
504 CardServices(ReleaseConfiguration, link->handle);
505 break;
506 case CS_EVENT_PM_RESUME:
507 link->state &= ~DEV_SUSPEND;
508 /* Fall through... */
509 case CS_EVENT_CARD_RESET:
510 if (link->state & DEV_CONFIG)
511 CardServices(RequestConfiguration, link->handle, &link->conf);
512 break;
513 }
514 return 0;
515 } /* avmcs_event */
516
517 /*====================================================================*/
518
avmcs_init(void)519 static int __init avmcs_init(void)
520 {
521 servinfo_t serv;
522 CardServices(GetCardServicesInfo, &serv);
523 if (serv.Revision != CS_RELEASE_CODE) {
524 printk(KERN_NOTICE "avm_cs: Card Services release "
525 "does not match!\n");
526 return -1;
527 }
528 register_pccard_driver(&dev_info, &avmcs_attach, &avmcs_detach);
529 return 0;
530 }
531
avmcs_exit(void)532 static void __exit avmcs_exit(void)
533 {
534 unregister_pccard_driver(&dev_info);
535 while (dev_list != NULL) {
536 if (dev_list->state & DEV_CONFIG)
537 avmcs_release((u_long)dev_list);
538 avmcs_detach(dev_list);
539 }
540 }
541
542 module_init(avmcs_init);
543 module_exit(avmcs_exit);
544