Linux-2.6.12-rc2
[cascardo/linux.git] / drivers / isdn / hisax / teles_cs.c
1 /* $Id: teles_cs.c,v 1.1.2.2 2004/01/25 15:07:06 keil Exp $ */
2 /*======================================================================
3
4     A teles S0 PCMCIA client driver
5
6     Based on skeleton by David Hinds, dhinds@allegro.stanford.edu
7     Written by Christof Petig, christof.petig@wtal.de
8     
9     Also inspired by ELSA PCMCIA driver 
10     by Klaus Lichtenwalder <Lichtenwalder@ACM.org>
11     
12     Extentions to new hisax_pcmcia by Karsten Keil
13
14     minor changes to be compatible with kernel 2.4.x
15     by Jan.Schubert@GMX.li
16
17 ======================================================================*/
18
19 #include <linux/kernel.h>
20 #include <linux/module.h>
21 #include <linux/init.h>
22 #include <linux/sched.h>
23 #include <linux/ptrace.h>
24 #include <linux/slab.h>
25 #include <linux/string.h>
26 #include <linux/timer.h>
27 #include <linux/ioport.h>
28 #include <asm/io.h>
29 #include <asm/system.h>
30
31 #include <pcmcia/version.h>
32 #include <pcmcia/cs_types.h>
33 #include <pcmcia/cs.h>
34 #include <pcmcia/cistpl.h>
35 #include <pcmcia/cisreg.h>
36 #include <pcmcia/ds.h>
37 #include "hisax_cfg.h"
38
39 MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for Teles PCMCIA cards");
40 MODULE_AUTHOR("Christof Petig, christof.petig@wtal.de, Karsten Keil, kkeil@suse.de");
41 MODULE_LICENSE("GPL");
42
43 /*
44    All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
45    you do not define PCMCIA_DEBUG at all, all the debug code will be
46    left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
47    be present but disabled -- but it can then be enabled for specific
48    modules at load time with a 'pc_debug=#' option to insmod.
49 */
50
51 #ifdef PCMCIA_DEBUG
52 static int pc_debug = PCMCIA_DEBUG;
53 module_param(pc_debug, int, 0);
54 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
55 static char *version =
56 "teles_cs.c 2.10 2002/07/30 22:23:34 kkeil";
57 #else
58 #define DEBUG(n, args...)
59 #endif
60
61 /*====================================================================*/
62
63 /* Parameters that can be set with 'insmod' */
64
65 static int protocol = 2;        /* EURO-ISDN Default */
66 module_param(protocol, int, 0);
67
68 /*====================================================================*/
69
70 /*
71    The event() function is this driver's Card Services event handler.
72    It will be called by Card Services when an appropriate card status
73    event is received.  The config() and release() entry points are
74    used to configure or release a socket, in response to card insertion
75    and ejection events.  They are invoked from the teles_cs event
76    handler.
77 */
78
79 static void teles_cs_config(dev_link_t *link);
80 static void teles_cs_release(dev_link_t *link);
81 static int teles_cs_event(event_t event, int priority,
82                           event_callback_args_t *args);
83
84 /*
85    The attach() and detach() entry points are used to create and destroy
86    "instances" of the driver, where each instance represents everything
87    needed to manage one actual PCMCIA card.
88 */
89
90 static dev_link_t *teles_attach(void);
91 static void teles_detach(dev_link_t *);
92
93 /*
94    The dev_info variable is the "key" that is used to match up this
95    device driver with appropriate cards, through the card configuration
96    database.
97 */
98
99 static dev_info_t dev_info = "teles_cs";
100
101 /*
102    A linked list of "instances" of the teles_cs device.  Each actual
103    PCMCIA card corresponds to one device instance, and is described
104    by one dev_link_t structure (defined in ds.h).
105
106    You may not want to use a linked list for this -- for example, the
107    memory card driver uses an array of dev_link_t pointers, where minor
108    device numbers are used to derive the corresponding array index.
109 */
110
111 static dev_link_t *dev_list = NULL;
112
113 /*
114    A dev_link_t structure has fields for most things that are needed
115    to keep track of a socket, but there will usually be some device
116    specific information that also needs to be kept track of.  The
117    'priv' pointer in a dev_link_t structure can be used to point to
118    a device-specific private data structure, like this.
119
120    To simplify the data structure handling, we actually include the
121    dev_link_t structure in the device's private data structure.
122
123    A driver needs to provide a dev_node_t structure for each device
124    on a card.  In some cases, there is only one device per card (for
125    example, ethernet cards, modems).  In other cases, there may be
126    many actual or logical devices (SCSI adapters, memory cards with
127    multiple partitions).  The dev_node_t structures need to be kept
128    in a linked list starting at the 'dev' field of a dev_link_t
129    structure.  We allocate them in the card's private data structure,
130    because they generally shouldn't be allocated dynamically.
131    In this case, we also provide a flag to indicate if a device is
132    "stopped" due to a power management event, or card ejection.  The
133    device IO routines can use a flag like this to throttle IO to a
134    card that is not ready to accept it.
135 */
136
137 typedef struct local_info_t {
138     dev_link_t          link;
139     dev_node_t          node;
140     int                 busy;
141     int                 cardnr;
142 } local_info_t;
143
144 /*======================================================================
145
146     teles_attach() creates an "instance" of the driver, allocatingx
147     local data structures for one device.  The device is registered
148     with Card Services.
149
150     The dev_link structure is initialized, but we don't actually
151     configure the card at this point -- we wait until we receive a
152     card insertion event.
153
154 ======================================================================*/
155
156 static dev_link_t *teles_attach(void)
157 {
158     client_reg_t client_reg;
159     dev_link_t *link;
160     local_info_t *local;
161     int ret;
162
163     DEBUG(0, "teles_attach()\n");
164
165     /* Allocate space for private device-specific data */
166     local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
167     if (!local) return NULL;
168     memset(local, 0, sizeof(local_info_t));
169     local->cardnr = -1;
170     link = &local->link; link->priv = local;
171
172     /* Interrupt setup */
173     link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
174     link->irq.IRQInfo1 = IRQ_LEVEL_ID|IRQ_SHARE_ID;
175     link->irq.Handler = NULL;
176
177     /*
178       General socket configuration defaults can go here.  In this
179       client, we assume very little, and rely on the CIS for almost
180       everything.  In most clients, many details (i.e., number, sizes,
181       and attributes of IO windows) are fixed by the nature of the
182       device, and can be hard-wired here.
183     */
184     link->io.NumPorts1 = 96;
185     link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
186     link->io.IOAddrLines = 5;
187
188     link->conf.Attributes = CONF_ENABLE_IRQ;
189     link->conf.Vcc = 50;
190     link->conf.IntType = INT_MEMORY_AND_IO;
191
192     /* Register with Card Services */
193     link->next = dev_list;
194     dev_list = link;
195     client_reg.dev_info = &dev_info;
196     client_reg.EventMask =
197         CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
198         CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
199         CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
200     client_reg.event_handler = &teles_cs_event;
201     client_reg.Version = 0x0210;
202     client_reg.event_callback_args.client_data = link;
203     ret = pcmcia_register_client(&link->handle, &client_reg);
204     if (ret != CS_SUCCESS) {
205         cs_error(link->handle, RegisterClient, ret);
206         teles_detach(link);
207         return NULL;
208     }
209
210     return link;
211 } /* teles_attach */
212
213 /*======================================================================
214
215     This deletes a driver "instance".  The device is de-registered
216     with Card Services.  If it has been released, all local data
217     structures are freed.  Otherwise, the structures will be freed
218     when the device is released.
219
220 ======================================================================*/
221
222 static void teles_detach(dev_link_t *link)
223 {
224     dev_link_t **linkp;
225     local_info_t *info = link->priv;
226     int ret;
227
228     DEBUG(0, "teles_detach(0x%p)\n", link);
229
230     /* Locate device structure */
231     for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
232         if (*linkp == link) break;
233     if (*linkp == NULL)
234         return;
235
236     if (link->state & DEV_CONFIG)
237         teles_cs_release(link);
238
239     /* Break the link with Card Services */
240     if (link->handle) {
241         ret = pcmcia_deregister_client(link->handle);
242         if (ret != CS_SUCCESS)
243             cs_error(link->handle, DeregisterClient, ret);
244     }
245
246     /* Unlink device structure and free it */
247     *linkp = link->next;
248     kfree(info);
249
250 } /* teles_detach */
251
252 /*======================================================================
253
254     teles_cs_config() is scheduled to run after a CARD_INSERTION event
255     is received, to configure the PCMCIA socket, and to make the
256     device available to the system.
257
258 ======================================================================*/
259 static int get_tuple(client_handle_t handle, tuple_t *tuple,
260                      cisparse_t *parse)
261 {
262     int i = pcmcia_get_tuple_data(handle, tuple);
263     if (i != CS_SUCCESS) return i;
264     return pcmcia_parse_tuple(handle, tuple, parse);
265 }
266
267 static int first_tuple(client_handle_t handle, tuple_t *tuple,
268                      cisparse_t *parse)
269 {
270     int i = pcmcia_get_first_tuple(handle, tuple);
271     if (i != CS_SUCCESS) return i;
272     return get_tuple(handle, tuple, parse);
273 }
274
275 static int next_tuple(client_handle_t handle, tuple_t *tuple,
276                      cisparse_t *parse)
277 {
278     int i = pcmcia_get_next_tuple(handle, tuple);
279     if (i != CS_SUCCESS) return i;
280     return get_tuple(handle, tuple, parse);
281 }
282
283 static void teles_cs_config(dev_link_t *link)
284 {
285     client_handle_t handle;
286     tuple_t tuple;
287     cisparse_t parse;
288     local_info_t *dev;
289     int i, j, last_fn;
290     u_short buf[128];
291     cistpl_cftable_entry_t *cf = &parse.cftable_entry;
292     IsdnCard_t icard;
293
294     DEBUG(0, "teles_config(0x%p)\n", link);
295     handle = link->handle;
296     dev = link->priv;
297
298     /*
299        This reads the card's CONFIG tuple to find its configuration
300        registers.
301     */
302     tuple.DesiredTuple = CISTPL_CONFIG;
303     tuple.TupleData = (cisdata_t *)buf;
304     tuple.TupleDataMax = 255;
305     tuple.TupleOffset = 0;
306     tuple.Attributes = 0;
307     i = first_tuple(handle, &tuple, &parse);
308     if (i != CS_SUCCESS) {
309         last_fn = ParseTuple;
310         goto cs_failed;
311     }
312     link->conf.ConfigBase = parse.config.base;
313     link->conf.Present = parse.config.rmask[0];
314
315     /* Configure card */
316     link->state |= DEV_CONFIG;
317
318     tuple.TupleData = (cisdata_t *)buf;
319     tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
320     tuple.Attributes = 0;
321     tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
322     i = first_tuple(handle, &tuple, &parse);
323     while (i == CS_SUCCESS) {
324         if ( (cf->io.nwin > 0) && cf->io.win[0].base) {
325             printk(KERN_INFO "(teles_cs: looks like the 96 model)\n");
326             link->conf.ConfigIndex = cf->index;
327             link->io.BasePort1 = cf->io.win[0].base;
328             i = pcmcia_request_io(link->handle, &link->io);
329             if (i == CS_SUCCESS) break;
330         } else {
331           printk(KERN_INFO "(teles_cs: looks like the 97 model)\n");
332           link->conf.ConfigIndex = cf->index;
333           for (i = 0, j = 0x2f0; j > 0x100; j -= 0x10) {
334             link->io.BasePort1 = j;
335             i = pcmcia_request_io(link->handle, &link->io);
336             if (i == CS_SUCCESS) break;
337           }
338           break;
339         }
340         i = next_tuple(handle, &tuple, &parse);
341     }
342
343     if (i != CS_SUCCESS) {
344         last_fn = RequestIO;
345         goto cs_failed;
346     }
347
348     i = pcmcia_request_irq(link->handle, &link->irq);
349     if (i != CS_SUCCESS) {
350         link->irq.AssignedIRQ = 0;
351         last_fn = RequestIRQ;
352         goto cs_failed;
353     }
354
355     i = pcmcia_request_configuration(link->handle, &link->conf);
356     if (i != CS_SUCCESS) {
357       last_fn = RequestConfiguration;
358       goto cs_failed;
359     }
360
361     /* At this point, the dev_node_t structure(s) should be
362        initialized and arranged in a linked list at link->dev. *//*  */
363     sprintf(dev->node.dev_name, "teles");
364     dev->node.major = dev->node.minor = 0x0;
365
366     link->dev = &dev->node;
367
368     /* Finally, report what we've done */
369     printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d",
370            dev->node.dev_name, link->conf.ConfigIndex,
371            link->conf.Vcc/10, link->conf.Vcc%10);
372     if (link->conf.Vpp1)
373         printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10);
374     if (link->conf.Attributes & CONF_ENABLE_IRQ)
375         printk(", irq %d", link->irq.AssignedIRQ);
376     if (link->io.NumPorts1)
377         printk(", io 0x%04x-0x%04x", link->io.BasePort1,
378                link->io.BasePort1+link->io.NumPorts1-1);
379     if (link->io.NumPorts2)
380         printk(" & 0x%04x-0x%04x", link->io.BasePort2,
381                link->io.BasePort2+link->io.NumPorts2-1);
382     printk("\n");
383
384     link->state &= ~DEV_CONFIG_PENDING;
385
386     icard.para[0] = link->irq.AssignedIRQ;
387     icard.para[1] = link->io.BasePort1;
388     icard.protocol = protocol;
389     icard.typ = ISDN_CTYPE_TELESPCMCIA;
390     
391     i = hisax_init_pcmcia(link, &(((local_info_t*)link->priv)->busy), &icard);
392     if (i < 0) {
393         printk(KERN_ERR "teles_cs: failed to initialize Teles PCMCIA %d at i/o %#x\n",
394                 i, link->io.BasePort1);
395         teles_cs_release(link);
396     } else
397         ((local_info_t*)link->priv)->cardnr = i;
398
399     return;
400 cs_failed:
401     cs_error(link->handle, last_fn, i);
402     teles_cs_release(link);
403 } /* teles_cs_config */
404
405 /*======================================================================
406
407     After a card is removed, teles_cs_release() will unregister the net
408     device, and release the PCMCIA configuration.  If the device is
409     still open, this will be postponed until it is closed.
410
411 ======================================================================*/
412
413 static void teles_cs_release(dev_link_t *link)
414 {
415     local_info_t *local = link->priv;
416
417     DEBUG(0, "teles_cs_release(0x%p)\n", link);
418
419     if (local) {
420         if (local->cardnr >= 0) {
421             /* no unregister function with hisax */
422             HiSax_closecard(local->cardnr);
423         }
424     }
425     /* Unlink the device chain */
426     link->dev = NULL;
427
428     /* Don't bother checking to see if these succeed or not */
429     if (link->win)
430         pcmcia_release_window(link->win);
431     pcmcia_release_configuration(link->handle);
432     pcmcia_release_io(link->handle, &link->io);
433     pcmcia_release_irq(link->handle, &link->irq);
434     link->state &= ~DEV_CONFIG;
435 } /* teles_cs_release */
436
437 /*======================================================================
438
439     The card status event handler.  Mostly, this schedules other
440     stuff to run after an event is received.  A CARD_REMOVAL event
441     also sets some flags to discourage the net drivers from trying
442     to talk to the card any more.
443
444     When a CARD_REMOVAL event is received, we immediately set a flag
445     to block future accesses to this device.  All the functions that
446     actually access the device should check this flag to make sure
447     the card is still present.
448
449 ======================================================================*/
450
451 static int teles_cs_event(event_t event, int priority,
452                           event_callback_args_t *args)
453 {
454     dev_link_t *link = args->client_data;
455     local_info_t *dev = link->priv;
456
457     DEBUG(1, "teles_cs_event(%d)\n", event);
458
459     switch (event) {
460     case CS_EVENT_CARD_REMOVAL:
461         link->state &= ~DEV_PRESENT;
462         if (link->state & DEV_CONFIG) {
463             ((local_info_t*)link->priv)->busy = 1;
464             teles_cs_release(link);
465         }
466         break;
467     case CS_EVENT_CARD_INSERTION:
468         link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
469         teles_cs_config(link);
470         break;
471     case CS_EVENT_PM_SUSPEND:
472         link->state |= DEV_SUSPEND;
473         /* Fall through... */
474     case CS_EVENT_RESET_PHYSICAL:
475         /* Mark the device as stopped, to block IO until later */
476         dev->busy = 1;
477         if (link->state & DEV_CONFIG)
478             pcmcia_release_configuration(link->handle);
479         break;
480     case CS_EVENT_PM_RESUME:
481         link->state &= ~DEV_SUSPEND;
482         /* Fall through... */
483     case CS_EVENT_CARD_RESET:
484         if (link->state & DEV_CONFIG)
485             pcmcia_request_configuration(link->handle, &link->conf);
486         dev->busy = 0;
487         break;
488     }
489     return 0;
490 } /* teles_cs_event */
491
492 static struct pcmcia_driver teles_cs_driver = {
493         .owner          = THIS_MODULE,
494         .drv            = {
495                 .name   = "teles_cs",
496         },
497         .attach         = teles_attach,
498         .detach         = teles_detach,
499 };
500
501 static int __init init_teles_cs(void)
502 {
503         return pcmcia_register_driver(&teles_cs_driver);
504 }
505
506 static void __exit exit_teles_cs(void)
507 {
508         pcmcia_unregister_driver(&teles_cs_driver);
509         BUG_ON(dev_list != NULL);
510 }
511
512 module_init(init_teles_cs);
513 module_exit(exit_teles_cs);