0a8c1da10b4b1c30af1b04284fdf8bf8b2791f78
[powerpc.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(struct pcmcia_device *p_dev);
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 /*
87    A driver needs to provide a dev_node_t structure for each device
88    on a card.  In some cases, there is only one device per card (for
89    example, ethernet cards, modems).  In other cases, there may be
90    many actual or logical devices (SCSI adapters, memory cards with
91    multiple partitions).  The dev_node_t structures need to be kept
92    in a linked list starting at the 'dev' field of a dev_link_t
93    structure.  We allocate them in the card's private data structure,
94    because they generally can't be allocated dynamically.
95 */
96    
97 typedef struct local_info_t {
98     dev_node_t  node;
99 } local_info_t;
100
101 /*======================================================================
102
103     avmcs_attach() creates an "instance" of the driver, allocating
104     local data structures for one device.  The device is registered
105     with Card Services.
106
107     The dev_link structure is initialized, but we don't actually
108     configure the card at this point -- we wait until we receive a
109     card insertion event.
110     
111 ======================================================================*/
112
113 static dev_link_t *avmcs_attach(void)
114 {
115     client_reg_t client_reg;
116     dev_link_t *link;
117     local_info_t *local;
118     int ret;
119     
120     /* Initialize the dev_link_t structure */
121     link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
122     if (!link)
123         goto err;
124     memset(link, 0, sizeof(struct dev_link_t));
125
126     /* The io structure describes IO port mapping */
127     link->io.NumPorts1 = 16;
128     link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
129     link->io.NumPorts2 = 0;
130
131     /* Interrupt setup */
132     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
133     link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
134
135     link->irq.IRQInfo1 = IRQ_LEVEL_ID;
136     
137     /* General socket configuration */
138     link->conf.Attributes = CONF_ENABLE_IRQ;
139     link->conf.Vcc = 50;
140     link->conf.IntType = INT_MEMORY_AND_IO;
141     link->conf.ConfigIndex = 1;
142     link->conf.Present = PRESENT_OPTION;
143
144     /* Allocate space for private device-specific data */
145     local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
146     if (!local)
147         goto err_kfree;
148     memset(local, 0, sizeof(local_info_t));
149     link->priv = local;
150     
151     /* Register with Card Services */
152     link->next = NULL;
153     client_reg.dev_info = &dev_info;
154     client_reg.Version = 0x0210;
155     client_reg.event_callback_args.client_data = link;
156     ret = pcmcia_register_client(&link->handle, &client_reg);
157     if (ret != 0) {
158         cs_error(link->handle, RegisterClient, ret);
159         avmcs_detach(link->handle);
160         goto err;
161     }
162     return link;
163
164  err_kfree:
165     kfree(link);
166  err:
167     return NULL;
168 } /* avmcs_attach */
169
170 /*======================================================================
171
172     This deletes a driver "instance".  The device is de-registered
173     with Card Services.  If it has been released, all local data
174     structures are freed.  Otherwise, the structures will be freed
175     when the device is released.
176
177 ======================================================================*/
178
179 static void avmcs_detach(struct pcmcia_device *p_dev)
180 {
181     dev_link_t *link = dev_to_instance(p_dev);
182
183     if (link->state & DEV_CONFIG)
184         avmcs_release(link);
185
186     kfree(link->priv);
187     kfree(link);
188 } /* avmcs_detach */
189
190 /*======================================================================
191
192     avmcs_config() is scheduled to run after a CARD_INSERTION event
193     is received, to configure the PCMCIA socket, and to make the
194     ethernet device available to the system.
195     
196 ======================================================================*/
197
198 static int get_tuple(client_handle_t handle, tuple_t *tuple,
199                      cisparse_t *parse)
200 {
201     int i = pcmcia_get_tuple_data(handle, tuple);
202     if (i != CS_SUCCESS) return i;
203     return pcmcia_parse_tuple(handle, tuple, parse);
204 }
205
206 static int first_tuple(client_handle_t handle, tuple_t *tuple,
207                      cisparse_t *parse)
208 {
209     int i = pcmcia_get_first_tuple(handle, tuple);
210     if (i != CS_SUCCESS) return i;
211     return get_tuple(handle, tuple, parse);
212 }
213
214 static int next_tuple(client_handle_t handle, tuple_t *tuple,
215                      cisparse_t *parse)
216 {
217     int i = pcmcia_get_next_tuple(handle, tuple);
218     if (i != CS_SUCCESS) return i;
219     return get_tuple(handle, tuple, parse);
220 }
221
222 static void avmcs_config(dev_link_t *link)
223 {
224     client_handle_t handle;
225     tuple_t tuple;
226     cisparse_t parse;
227     cistpl_cftable_entry_t *cf = &parse.cftable_entry;
228     local_info_t *dev;
229     int i;
230     u_char buf[64];
231     char devname[128];
232     int cardtype;
233     int (*addcard)(unsigned int port, unsigned irq);
234     
235     handle = link->handle;
236     dev = link->priv;
237
238     /*
239        This reads the card's CONFIG tuple to find its configuration
240        registers.
241     */
242     do {
243         tuple.DesiredTuple = CISTPL_CONFIG;
244         i = pcmcia_get_first_tuple(handle, &tuple);
245         if (i != CS_SUCCESS) break;
246         tuple.TupleData = buf;
247         tuple.TupleDataMax = 64;
248         tuple.TupleOffset = 0;
249         i = pcmcia_get_tuple_data(handle, &tuple);
250         if (i != CS_SUCCESS) break;
251         i = pcmcia_parse_tuple(handle, &tuple, &parse);
252         if (i != CS_SUCCESS) break;
253         link->conf.ConfigBase = parse.config.base;
254     } while (0);
255     if (i != CS_SUCCESS) {
256         cs_error(link->handle, ParseTuple, i);
257         link->state &= ~DEV_CONFIG_PENDING;
258         return;
259     }
260     
261     /* Configure card */
262     link->state |= DEV_CONFIG;
263
264     do {
265
266         tuple.Attributes = 0;
267         tuple.TupleData = buf;
268         tuple.TupleDataMax = 254;
269         tuple.TupleOffset = 0;
270         tuple.DesiredTuple = CISTPL_VERS_1;
271
272         devname[0] = 0;
273         if( !first_tuple(handle, &tuple, &parse) && parse.version_1.ns > 1 ) {
274             strlcpy(devname,parse.version_1.str + parse.version_1.ofs[1], 
275                         sizeof(devname));
276         }
277         /*
278          * find IO port
279          */
280         tuple.TupleData = (cisdata_t *)buf;
281         tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
282         tuple.Attributes = 0;
283         tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
284         i = first_tuple(handle, &tuple, &parse);
285         while (i == CS_SUCCESS) {
286             if (cf->io.nwin > 0) {
287                 link->conf.ConfigIndex = cf->index;
288                 link->io.BasePort1 = cf->io.win[0].base;
289                 link->io.NumPorts1 = cf->io.win[0].len;
290                 link->io.NumPorts2 = 0;
291                 printk(KERN_INFO "avm_cs: testing i/o %#x-%#x\n",
292                         link->io.BasePort1,
293                         link->io.BasePort1+link->io.NumPorts1-1);
294                 i = pcmcia_request_io(link->handle, &link->io);
295                 if (i == CS_SUCCESS) goto found_port;
296             }
297             i = next_tuple(handle, &tuple, &parse);
298         }
299
300 found_port:
301         if (i != CS_SUCCESS) {
302             cs_error(link->handle, RequestIO, i);
303             break;
304         }
305         
306         /*
307          * allocate an interrupt line
308          */
309         i = pcmcia_request_irq(link->handle, &link->irq);
310         if (i != CS_SUCCESS) {
311             cs_error(link->handle, RequestIRQ, i);
312             pcmcia_release_io(link->handle, &link->io);
313             break;
314         }
315         
316         /*
317          * configure the PCMCIA socket
318           */
319         i = pcmcia_request_configuration(link->handle, &link->conf);
320         if (i != CS_SUCCESS) {
321             cs_error(link->handle, RequestConfiguration, i);
322             pcmcia_release_io(link->handle, &link->io);
323             pcmcia_release_irq(link->handle, &link->irq);
324             break;
325         }
326
327     } while (0);
328
329     /* At this point, the dev_node_t structure(s) should be
330        initialized and arranged in a linked list at link->dev. */
331
332     if (devname[0]) {
333         char *s = strrchr(devname, ' ');
334         if (!s)
335            s = devname;
336         else s++;
337         strcpy(dev->node.dev_name, s);
338         if (strcmp("M1", s) == 0) {
339            cardtype = AVM_CARDTYPE_M1;
340         } else if (strcmp("M2", s) == 0) {
341            cardtype = AVM_CARDTYPE_M2;
342         } else {
343            cardtype = AVM_CARDTYPE_B1;
344         }
345     } else {
346         strcpy(dev->node.dev_name, "b1");
347         cardtype = AVM_CARDTYPE_B1;
348     }
349
350     dev->node.major = 64;
351     dev->node.minor = 0;
352     link->dev = &dev->node;
353     
354     link->state &= ~DEV_CONFIG_PENDING;
355     /* If any step failed, release any partially configured state */
356     if (i != 0) {
357         avmcs_release(link);
358         return;
359     }
360
361
362     switch (cardtype) {
363         case AVM_CARDTYPE_M1: addcard = b1pcmcia_addcard_m1; break;
364         case AVM_CARDTYPE_M2: addcard = b1pcmcia_addcard_m2; break;
365         default:
366         case AVM_CARDTYPE_B1: addcard = b1pcmcia_addcard_b1; break;
367     }
368     if ((i = (*addcard)(link->io.BasePort1, link->irq.AssignedIRQ)) < 0) {
369         printk(KERN_ERR "avm_cs: failed to add AVM-%s-Controller at i/o %#x, irq %d\n",
370                 dev->node.dev_name, link->io.BasePort1, link->irq.AssignedIRQ);
371         avmcs_release(link);
372         return;
373     }
374     dev->node.minor = i;
375
376 } /* avmcs_config */
377
378 /*======================================================================
379
380     After a card is removed, avmcs_release() will unregister the net
381     device, and release the PCMCIA configuration.  If the device is
382     still open, this will be postponed until it is closed.
383     
384 ======================================================================*/
385
386 static void avmcs_release(dev_link_t *link)
387 {
388     b1pcmcia_delcard(link->io.BasePort1, link->irq.AssignedIRQ);
389
390     /* Unlink the device chain */
391     link->dev = NULL;
392     
393     /* Don't bother checking to see if these succeed or not */
394     pcmcia_release_configuration(link->handle);
395     pcmcia_release_io(link->handle, &link->io);
396     pcmcia_release_irq(link->handle, &link->irq);
397     link->state &= ~DEV_CONFIG;
398 } /* avmcs_release */
399
400 static int avmcs_suspend(struct pcmcia_device *dev)
401 {
402         dev_link_t *link = dev_to_instance(dev);
403
404         link->state |= DEV_SUSPEND;
405         if (link->state & DEV_CONFIG)
406                 pcmcia_release_configuration(link->handle);
407
408         return 0;
409 }
410
411 static int avmcs_resume(struct pcmcia_device *dev)
412 {
413         dev_link_t *link = dev_to_instance(dev);
414
415         link->state &= ~DEV_SUSPEND;
416         if (link->state & DEV_CONFIG)
417                 pcmcia_request_configuration(link->handle, &link->conf);
418
419         return 0;
420 }
421
422 /*======================================================================
423
424     The card status event handler.  Mostly, this schedules other
425     stuff to run after an event is received.  A CARD_REMOVAL event
426     also sets some flags to discourage the net drivers from trying
427     to talk to the card any more.
428
429     When a CARD_REMOVAL event is received, we immediately set a flag
430     to block future accesses to this device.  All the functions that
431     actually access the device should check this flag to make sure
432     the card is still present.
433     
434 ======================================================================*/
435
436 static int avmcs_event(event_t event, int priority,
437                           event_callback_args_t *args)
438 {
439     dev_link_t *link = args->client_data;
440
441     switch (event) {
442     case CS_EVENT_CARD_INSERTION:
443         link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
444         avmcs_config(link);
445         break;
446     }
447     return 0;
448 } /* avmcs_event */
449
450 static struct pcmcia_device_id avmcs_ids[] = {
451         PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN-Controller B1", 0x95d42008, 0x845dc335),
452         PCMCIA_DEVICE_PROD_ID12("AVM", "Mobile ISDN-Controller M1", 0x95d42008, 0x81e10430),
453         PCMCIA_DEVICE_PROD_ID12("AVM", "Mobile ISDN-Controller M2", 0x95d42008, 0x18e8558a),
454         PCMCIA_DEVICE_NULL
455 };
456 MODULE_DEVICE_TABLE(pcmcia, avmcs_ids);
457
458 static struct pcmcia_driver avmcs_driver = {
459         .owner  = THIS_MODULE,
460         .drv    = {
461                 .name   = "avm_cs",
462         },
463         .attach = avmcs_attach,
464         .event  = avmcs_event,
465         .remove = avmcs_detach,
466         .id_table = avmcs_ids,
467         .suspend= avmcs_suspend,
468         .resume = avmcs_resume,
469 };
470
471 static int __init avmcs_init(void)
472 {
473         return pcmcia_register_driver(&avmcs_driver);
474 }
475
476 static void __exit avmcs_exit(void)
477 {
478         pcmcia_unregister_driver(&avmcs_driver);
479 }
480
481 module_init(avmcs_init);
482 module_exit(avmcs_exit);