[PATCH] pcmcia: new suspend core
[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/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     kfree(link->priv);
240     kfree(link);
241     
242 } /* avma1cs_detach */
243
244 /*======================================================================
245
246     avma1cs_config() is scheduled to run after a CARD_INSERTION event
247     is received, to configure the PCMCIA socket, and to make the
248     ethernet device available to the system.
249     
250 ======================================================================*/
251
252 static int get_tuple(client_handle_t handle, tuple_t *tuple,
253                      cisparse_t *parse)
254 {
255     int i = pcmcia_get_tuple_data(handle, tuple);
256     if (i != CS_SUCCESS) return i;
257     return pcmcia_parse_tuple(handle, tuple, parse);
258 }
259
260 static int first_tuple(client_handle_t handle, tuple_t *tuple,
261                      cisparse_t *parse)
262 {
263     int i = pcmcia_get_first_tuple(handle, tuple);
264     if (i != CS_SUCCESS) return i;
265     return get_tuple(handle, tuple, parse);
266 }
267
268 static int next_tuple(client_handle_t handle, tuple_t *tuple,
269                      cisparse_t *parse)
270 {
271     int i = pcmcia_get_next_tuple(handle, tuple);
272     if (i != CS_SUCCESS) return i;
273     return get_tuple(handle, tuple, parse);
274 }
275
276 static void avma1cs_config(dev_link_t *link)
277 {
278     client_handle_t handle;
279     tuple_t tuple;
280     cisparse_t parse;
281     cistpl_cftable_entry_t *cf = &parse.cftable_entry;
282     local_info_t *dev;
283     int i;
284     u_char buf[64];
285     char devname[128];
286     IsdnCard_t  icard;
287     int busy = 0;
288     
289     handle = link->handle;
290     dev = link->priv;
291
292     DEBUG(0, "avma1cs_config(0x%p)\n", link);
293
294     /*
295        This reads the card's CONFIG tuple to find its configuration
296        registers.
297     */
298     do {
299         tuple.DesiredTuple = CISTPL_CONFIG;
300         i = pcmcia_get_first_tuple(handle, &tuple);
301         if (i != CS_SUCCESS) break;
302         tuple.TupleData = buf;
303         tuple.TupleDataMax = 64;
304         tuple.TupleOffset = 0;
305         i = pcmcia_get_tuple_data(handle, &tuple);
306         if (i != CS_SUCCESS) break;
307         i = pcmcia_parse_tuple(handle, &tuple, &parse);
308         if (i != CS_SUCCESS) break;
309         link->conf.ConfigBase = parse.config.base;
310     } while (0);
311     if (i != CS_SUCCESS) {
312         cs_error(link->handle, ParseTuple, i);
313         link->state &= ~DEV_CONFIG_PENDING;
314         return;
315     }
316     
317     /* Configure card */
318     link->state |= DEV_CONFIG;
319
320     do {
321
322         tuple.Attributes = 0;
323         tuple.TupleData = buf;
324         tuple.TupleDataMax = 254;
325         tuple.TupleOffset = 0;
326         tuple.DesiredTuple = CISTPL_VERS_1;
327
328         devname[0] = 0;
329         if( !first_tuple(handle, &tuple, &parse) && parse.version_1.ns > 1 ) {
330             strlcpy(devname,parse.version_1.str + parse.version_1.ofs[1], 
331                         sizeof(devname));
332         }
333         /*
334          * find IO port
335          */
336         tuple.TupleData = (cisdata_t *)buf;
337         tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
338         tuple.Attributes = 0;
339         tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
340         i = first_tuple(handle, &tuple, &parse);
341         while (i == CS_SUCCESS) {
342             if (cf->io.nwin > 0) {
343                 link->conf.ConfigIndex = cf->index;
344                 link->io.BasePort1 = cf->io.win[0].base;
345                 link->io.NumPorts1 = cf->io.win[0].len;
346                 link->io.NumPorts2 = 0;
347                 printk(KERN_INFO "avma1_cs: testing i/o %#x-%#x\n",
348                         link->io.BasePort1,
349                         link->io.BasePort1+link->io.NumPorts1 - 1);
350                 i = pcmcia_request_io(link->handle, &link->io);
351                 if (i == CS_SUCCESS) goto found_port;
352             }
353             i = next_tuple(handle, &tuple, &parse);
354         }
355
356 found_port:
357         if (i != CS_SUCCESS) {
358             cs_error(link->handle, RequestIO, i);
359             break;
360         }
361         
362         /*
363          * allocate an interrupt line
364          */
365         i = pcmcia_request_irq(link->handle, &link->irq);
366         if (i != CS_SUCCESS) {
367             cs_error(link->handle, RequestIRQ, i);
368             pcmcia_release_io(link->handle, &link->io);
369             break;
370         }
371         
372         /*
373          * configure the PCMCIA socket
374          */
375         i = pcmcia_request_configuration(link->handle, &link->conf);
376         if (i != CS_SUCCESS) {
377             cs_error(link->handle, RequestConfiguration, i);
378             pcmcia_release_io(link->handle, &link->io);
379             pcmcia_release_irq(link->handle, &link->irq);
380             break;
381         }
382
383     } while (0);
384
385     /* At this point, the dev_node_t structure(s) should be
386        initialized and arranged in a linked list at link->dev. */
387
388     strcpy(dev->node.dev_name, "A1");
389     dev->node.major = 45;
390     dev->node.minor = 0;
391     link->dev = &dev->node;
392     
393     link->state &= ~DEV_CONFIG_PENDING;
394     /* If any step failed, release any partially configured state */
395     if (i != 0) {
396         avma1cs_release(link);
397         return;
398     }
399
400     printk(KERN_NOTICE "avma1_cs: checking at i/o %#x, irq %d\n",
401                                 link->io.BasePort1, link->irq.AssignedIRQ);
402
403     icard.para[0] = link->irq.AssignedIRQ;
404     icard.para[1] = link->io.BasePort1;
405     icard.protocol = isdnprot;
406     icard.typ = ISDN_CTYPE_A1_PCMCIA;
407     
408     i = hisax_init_pcmcia(link, &busy, &icard);
409     if (i < 0) {
410         printk(KERN_ERR "avma1_cs: failed to initialize AVM A1 PCMCIA %d at i/o %#x\n", i, link->io.BasePort1);
411         avma1cs_release(link);
412         return;
413     }
414     dev->node.minor = i;
415
416 } /* avma1cs_config */
417
418 /*======================================================================
419
420     After a card is removed, avma1cs_release() will unregister the net
421     device, and release the PCMCIA configuration.  If the device is
422     still open, this will be postponed until it is closed.
423     
424 ======================================================================*/
425
426 static void avma1cs_release(dev_link_t *link)
427 {
428     local_info_t *local = link->priv;
429
430     DEBUG(0, "avma1cs_release(0x%p)\n", link);
431
432     /* no unregister function with hisax */
433     HiSax_closecard(local->node.minor);
434
435     /* Unlink the device chain */
436     link->dev = NULL;
437     
438     /* Don't bother checking to see if these succeed or not */
439     pcmcia_release_configuration(link->handle);
440     pcmcia_release_io(link->handle, &link->io);
441     pcmcia_release_irq(link->handle, &link->irq);
442     link->state &= ~DEV_CONFIG;
443     
444     if (link->state & DEV_STALE_LINK)
445         avma1cs_detach(link);
446 } /* avma1cs_release */
447
448 static int avma1cs_suspend(struct pcmcia_device *dev)
449 {
450         dev_link_t *link = dev_to_instance(dev);
451
452         link->state |= DEV_SUSPEND;
453         if (link->state & DEV_CONFIG)
454                 pcmcia_release_configuration(link->handle);
455
456         return 0;
457 }
458
459 static int avma1cs_resume(struct pcmcia_device *dev)
460 {
461         dev_link_t *link = dev_to_instance(dev);
462
463         link->state &= ~DEV_SUSPEND;
464         if (link->state & DEV_CONFIG)
465                 pcmcia_request_configuration(link->handle, &link->conf);
466
467         return 0;
468 }
469
470 /*======================================================================
471
472     The card status event handler.  Mostly, this schedules other
473     stuff to run after an event is received.  A CARD_REMOVAL event
474     also sets some flags to discourage the net drivers from trying
475     to talk to the card any more.
476
477     When a CARD_REMOVAL event is received, we immediately set a flag
478     to block future accesses to this device.  All the functions that
479     actually access the device should check this flag to make sure
480     the card is still present.
481     
482 ======================================================================*/
483
484 static int avma1cs_event(event_t event, int priority,
485                           event_callback_args_t *args)
486 {
487     dev_link_t *link = args->client_data;
488
489     DEBUG(1, "avma1cs_event(0x%06x)\n", event);
490     
491     switch (event) {
492         case CS_EVENT_CARD_REMOVAL:
493             if (link->state & DEV_CONFIG)
494                 avma1cs_release(link);
495             break;
496         case CS_EVENT_CARD_INSERTION:
497             link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
498             avma1cs_config(link);
499             break;
500     }
501     return 0;
502 } /* avma1cs_event */
503
504 static struct pcmcia_device_id avma1cs_ids[] = {
505         PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN A", 0x95d42008, 0xadc9d4bb),
506         PCMCIA_DEVICE_PROD_ID12("ISDN", "CARD", 0x8d9761c8, 0x01c5aa7b),
507         PCMCIA_DEVICE_NULL
508 };
509 MODULE_DEVICE_TABLE(pcmcia, avma1cs_ids);
510
511 static struct pcmcia_driver avma1cs_driver = {
512         .owner          = THIS_MODULE,
513         .drv            = {
514                 .name   = "avma1_cs",
515         },
516         .attach         = avma1cs_attach,
517         .event          = avma1cs_event,
518         .detach         = avma1cs_detach,
519         .id_table       = avma1cs_ids,
520         .suspend        = avma1cs_suspend,
521         .resume         = avma1cs_resume,
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         BUG_ON(dev_list != NULL);
535 }
536
537 module_init(init_avma1_cs);
538 module_exit(exit_avma1_cs);