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