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