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