import of ftp.dlink.com/GPL/DSMG-600_reB/ppclinux.tar.gz
[linux-2.4.21-pre4.git] / drivers / isdn / avmb1 / avm_cs.c
1 /* $Id: avm_cs.c,v 1.1.1.1 2005/04/11 02:50:22 jack 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
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
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
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
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
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
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
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
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
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);