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