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/sched.h>
17 #include <linux/ptrace.h>
18 #include <linux/slab.h>
19 #include <linux/string.h>
20 #include <linux/timer.h>
21 #include <linux/init.h>
22 #include <asm/io.h>
23 #include <asm/system.h>
24 
25 #include <pcmcia/version.h>
26 #include <pcmcia/cs_types.h>
27 #include <pcmcia/cs.h>
28 #include <pcmcia/cistpl.h>
29 #include <pcmcia/ds.h>
30 
31 MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for AVM A1/Fritz!PCMCIA cards");
32 MODULE_AUTHOR("Carsten Paeth");
33 MODULE_LICENSE("GPL");
34 
35 int avm_a1_init_pcmcia(void *pcm_iob, int pcm_irq, int *busy_flag, int prot);
36 void HiSax_closecard(int cardnr);
37 
38 
39 /*
40    All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
41    you do not define PCMCIA_DEBUG at all, all the debug code will be
42    left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
43    be present but disabled -- but it can then be enabled for specific
44    modules at load time with a 'pc_debug=#' option to insmod.
45 */
46 #ifdef PCMCIA_DEBUG
47 static int pc_debug = PCMCIA_DEBUG;
48 MODULE_PARM(pc_debug, "i");
49 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
50 static char *version =
51 "avma1_cs.c 1.00 1998/01/23 10:00:00 (Carsten Paeth)";
52 #else
53 #define DEBUG(n, args...)
54 #endif
55 
56 /*====================================================================*/
57 
58 /* Parameters that can be set with 'insmod' */
59 
60 static int default_irq_list[11] = { 15, 13, 12, 11, 10, 9, 7, 5, 4, 3, -1 };
61 static int irq_list[11] = { -1 };
62 static int isdnprot = 2;
63 
64 MODULE_PARM(irq_list, "1-11i");
65 MODULE_PARM(isdnprot, "1-4i");
66 
67 /*====================================================================*/
68 
69 /*
70    The event() function is this driver's Card Services event handler.
71    It will be called by Card Services when an appropriate card status
72    event is received.  The config() and release() entry points are
73    used to configure or release a socket, in response to card insertion
74    and ejection events.  They are invoked from the skeleton event
75    handler.
76 */
77 
78 static void avma1cs_config(dev_link_t *link);
79 static void avma1cs_release(u_long arg);
80 static int avma1cs_event(event_t event, int priority,
81 			  event_callback_args_t *args);
82 
83 /*
84    The attach() and detach() entry points are used to create and destroy
85    "instances" of the driver, where each instance represents everything
86    needed to manage one actual PCMCIA card.
87 */
88 
89 static dev_link_t *avma1cs_attach(void);
90 static void avma1cs_detach(dev_link_t *);
91 
92 /*
93    The dev_info variable is the "key" that is used to match up this
94    device driver with appropriate cards, through the card configuration
95    database.
96 */
97 
98 static dev_info_t dev_info = "avma1_cs";
99 
100 /*
101    A linked list of "instances" of the skeleton device.  Each actual
102    PCMCIA card corresponds to one device instance, and is described
103    by one dev_link_t structure (defined in ds.h).
104 
105    You may not want to use a linked list for this -- for example, the
106    memory card driver uses an array of dev_link_t pointers, where minor
107    device numbers are used to derive the corresponding array index.
108 */
109 
110 static dev_link_t *dev_list = NULL;
111 
112 /*
113    A dev_link_t structure has fields for most things that are needed
114    to keep track of a socket, but there will usually be some device
115    specific information that also needs to be kept track of.  The
116    'priv' pointer in a dev_link_t structure can be used to point to
117    a device-specific private data structure, like this.
118 
119    A driver needs to provide a dev_node_t structure for each device
120    on a card.  In some cases, there is only one device per card (for
121    example, ethernet cards, modems).  In other cases, there may be
122    many actual or logical devices (SCSI adapters, memory cards with
123    multiple partitions).  The dev_node_t structures need to be kept
124    in a linked list starting at the 'dev' field of a dev_link_t
125    structure.  We allocate them in the card's private data structure,
126    because they generally can't be allocated dynamically.
127 */
128 
129 typedef struct local_info_t {
130     dev_node_t	node;
131 } local_info_t;
132 
133 /*====================================================================*/
134 
cs_error(client_handle_t handle,int func,int ret)135 static void cs_error(client_handle_t handle, int func, int ret)
136 {
137     error_info_t err = { func, ret };
138     CardServices(ReportError, handle, &err);
139 }
140 
141 /*======================================================================
142 
143     avma1cs_attach() creates an "instance" of the driver, allocating
144     local data structures for one device.  The device is registered
145     with Card Services.
146 
147     The dev_link structure is initialized, but we don't actually
148     configure the card at this point -- we wait until we receive a
149     card insertion event.
150 
151 ======================================================================*/
152 
avma1cs_attach(void)153 static dev_link_t *avma1cs_attach(void)
154 {
155     client_reg_t client_reg;
156     dev_link_t *link;
157     local_info_t *local;
158     int ret, i;
159 
160     DEBUG(0, "avma1cs_attach()\n");
161 
162     /* Initialize the dev_link_t structure */
163     link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
164     memset(link, 0, sizeof(struct dev_link_t));
165     link->release.function = &avma1cs_release;
166     link->release.data = (u_long)link;
167 
168     /* The io structure describes IO port mapping */
169     link->io.NumPorts1 = 16;
170     link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
171     link->io.NumPorts2 = 16;
172     link->io.Attributes2 = IO_DATA_PATH_WIDTH_16;
173     link->io.IOAddrLines = 5;
174 
175     /* Interrupt setup */
176     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
177     link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
178 
179     link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
180     if (irq_list[0] != -1) {
181 	    for (i = 0; i < 10 && irq_list[i] > 0; i++)
182 	       link->irq.IRQInfo2 |= 1 << irq_list[i];
183     } else {
184 	    for (i = 0; i < 10 && default_irq_list[i] > 0; i++)
185 	       link->irq.IRQInfo2 |= 1 << default_irq_list[i];
186     }
187 
188     /* General socket configuration */
189     link->conf.Attributes = CONF_ENABLE_IRQ;
190     link->conf.Vcc = 50;
191     link->conf.IntType = INT_MEMORY_AND_IO;
192     link->conf.ConfigIndex = 1;
193     link->conf.Present = PRESENT_OPTION;
194 
195     /* Allocate space for private device-specific data */
196     local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
197     memset(local, 0, sizeof(local_info_t));
198     link->priv = local;
199 
200     /* Register with Card Services */
201     link->next = dev_list;
202     dev_list = link;
203     client_reg.dev_info = &dev_info;
204     client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
205     client_reg.EventMask =
206 	CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
207 	CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
208 	CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
209     client_reg.event_handler = &avma1cs_event;
210     client_reg.Version = 0x0210;
211     client_reg.event_callback_args.client_data = link;
212     ret = CardServices(RegisterClient, &link->handle, &client_reg);
213     if (ret != 0) {
214 	cs_error(link->handle, RegisterClient, ret);
215 	avma1cs_detach(link);
216 	return NULL;
217     }
218 
219     return link;
220 } /* avma1cs_attach */
221 
222 /*======================================================================
223 
224     This deletes a driver "instance".  The device is de-registered
225     with Card Services.  If it has been released, all local data
226     structures are freed.  Otherwise, the structures will be freed
227     when the device is released.
228 
229 ======================================================================*/
230 
avma1cs_detach(dev_link_t * link)231 static void avma1cs_detach(dev_link_t *link)
232 {
233     dev_link_t **linkp;
234 
235     DEBUG(0, "avma1cs_detach(0x%p)\n", link);
236 
237     /* Locate device structure */
238     for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
239 	if (*linkp == link) break;
240     if (*linkp == NULL)
241 	return;
242 
243     /*
244        If the device is currently configured and active, we won't
245        actually delete it yet.  Instead, it is marked so that when
246        the release() function is called, that will trigger a proper
247        detach().
248     */
249     if (link->state & DEV_CONFIG) {
250 #ifdef PCMCIA_DEBUG
251 	printk(KERN_DEBUG "avma1_cs: detach postponed, '%s' "
252 	       "still locked\n", link->dev->dev_name);
253 #endif
254 	link->state |= DEV_STALE_LINK;
255 	return;
256     }
257 
258     /* Break the link with Card Services */
259     if (link->handle)
260 	CardServices(DeregisterClient, link->handle);
261 
262     /* Unlink device structure, free pieces */
263     *linkp = link->next;
264     if (link->priv) {
265 	kfree(link->priv);
266     }
267     kfree(link);
268 
269 } /* avma1cs_detach */
270 
271 /*======================================================================
272 
273     avma1cs_config() is scheduled to run after a CARD_INSERTION event
274     is received, to configure the PCMCIA socket, and to make the
275     ethernet device available to the system.
276 
277 ======================================================================*/
278 
get_tuple(int fn,client_handle_t handle,tuple_t * tuple,cisparse_t * parse)279 static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple,
280 		     cisparse_t *parse)
281 {
282     int i;
283     i = CardServices(fn, handle, tuple);
284     if (i != CS_SUCCESS) return i;
285     i = CardServices(GetTupleData, handle, tuple);
286     if (i != CS_SUCCESS) return i;
287     return CardServices(ParseTuple, handle, tuple, parse);
288 }
289 
290 #define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
291 #define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
292 
avma1cs_config(dev_link_t * link)293 static void avma1cs_config(dev_link_t *link)
294 {
295     client_handle_t handle;
296     tuple_t tuple;
297     cisparse_t parse;
298     cistpl_cftable_entry_t *cf = &parse.cftable_entry;
299     local_info_t *dev;
300     int i;
301     u_char buf[64];
302     char devname[128];
303     int busy = 0;
304 
305     handle = link->handle;
306     dev = link->priv;
307 
308     DEBUG(0, "avma1cs_config(0x%p)\n", link);
309 
310     /*
311        This reads the card's CONFIG tuple to find its configuration
312        registers.
313     */
314     do {
315 	tuple.DesiredTuple = CISTPL_CONFIG;
316 	i = CardServices(GetFirstTuple, handle, &tuple);
317 	if (i != CS_SUCCESS) break;
318 	tuple.TupleData = buf;
319 	tuple.TupleDataMax = 64;
320 	tuple.TupleOffset = 0;
321 	i = CardServices(GetTupleData, handle, &tuple);
322 	if (i != CS_SUCCESS) break;
323 	i = CardServices(ParseTuple, handle, &tuple, &parse);
324 	if (i != CS_SUCCESS) break;
325 	link->conf.ConfigBase = parse.config.base;
326     } while (0);
327     if (i != CS_SUCCESS) {
328 	cs_error(link->handle, ParseTuple, i);
329 	link->state &= ~DEV_CONFIG_PENDING;
330 	return;
331     }
332 
333     /* Configure card */
334     link->state |= DEV_CONFIG;
335 
336     do {
337 
338 	tuple.Attributes = 0;
339 	tuple.TupleData = buf;
340 	tuple.TupleDataMax = 254;
341 	tuple.TupleOffset = 0;
342 	tuple.DesiredTuple = CISTPL_VERS_1;
343 
344 	devname[0] = 0;
345 	if( !first_tuple(handle, &tuple, &parse) && parse.version_1.ns > 1 ) {
346 	    strncpy(devname,parse.version_1.str + parse.version_1.ofs[1],
347 			sizeof(devname));
348 	}
349 	/*
350          * find IO port
351          */
352 	tuple.TupleData = (cisdata_t *)buf;
353 	tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
354 	tuple.Attributes = 0;
355 	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
356 	i = first_tuple(handle, &tuple, &parse);
357 	while (i == CS_SUCCESS) {
358 	    if (cf->io.nwin > 0) {
359 		link->conf.ConfigIndex = cf->index;
360 		link->io.BasePort1 = cf->io.win[0].base;
361 		link->io.NumPorts1 = cf->io.win[0].len;
362 		link->io.NumPorts2 = 0;
363                 printk(KERN_INFO "avma1_cs: testing i/o %#x-%#x\n",
364 			link->io.BasePort1,
365 		        link->io.BasePort1+link->io.NumPorts1 - 1);
366 		i = CardServices(RequestIO, link->handle, &link->io);
367 		if (i == CS_SUCCESS) goto found_port;
368 	    }
369 	    i = next_tuple(handle, &tuple, &parse);
370 	}
371 
372 found_port:
373 	if (i != CS_SUCCESS) {
374 	    cs_error(link->handle, RequestIO, i);
375 	    break;
376 	}
377 
378 	/*
379 	 * allocate an interrupt line
380 	 */
381 	i = CardServices(RequestIRQ, link->handle, &link->irq);
382 	if (i != CS_SUCCESS) {
383 	    cs_error(link->handle, RequestIRQ, i);
384 	    CardServices(ReleaseIO, link->handle, &link->io);
385 	    break;
386 	}
387 
388 	/*
389          * configure the PCMCIA socket
390 	  */
391 	i = CardServices(RequestConfiguration, link->handle, &link->conf);
392 	if (i != CS_SUCCESS) {
393 	    cs_error(link->handle, RequestConfiguration, i);
394 	    CardServices(ReleaseIO, link->handle, &link->io);
395 	    CardServices(ReleaseIRQ, link->handle, &link->irq);
396 	    break;
397 	}
398 
399     } while (0);
400 
401     /* At this point, the dev_node_t structure(s) should be
402        initialized and arranged in a linked list at link->dev. */
403 
404     strcpy(dev->node.dev_name, "A1");
405     dev->node.major = 45;
406     dev->node.minor = 0;
407     link->dev = &dev->node;
408 
409     link->state &= ~DEV_CONFIG_PENDING;
410     /* If any step failed, release any partially configured state */
411     if (i != 0) {
412 	avma1cs_release((u_long)link);
413 	return;
414     }
415 
416     printk(KERN_NOTICE "avma1_cs: checking at i/o %#x, irq %d\n",
417 				link->io.BasePort1, link->irq.AssignedIRQ);
418 
419     if (avm_a1_init_pcmcia((void *)(int)link->io.BasePort1,
420                            link->irq.AssignedIRQ,
421                            &busy, isdnprot) != 0) {
422        printk(KERN_ERR "avma1_cs: failed to initialize AVM A1 PCMCIA %d at i/o %#x\n", i, link->io.BasePort1);
423        return;
424     }
425 
426     i = 0; /* no returncode for cardnr :-( */
427 
428     dev->node.minor = i;
429 
430 } /* avma1cs_config */
431 
432 /*======================================================================
433 
434     After a card is removed, avma1cs_release() will unregister the net
435     device, and release the PCMCIA configuration.  If the device is
436     still open, this will be postponed until it is closed.
437 
438 ======================================================================*/
439 
avma1cs_release(u_long arg)440 static void avma1cs_release(u_long arg)
441 {
442     dev_link_t *link = (dev_link_t *)arg;
443     local_info_t *local = link->priv;
444 
445     DEBUG(0, "avma1cs_release(0x%p)\n", link);
446 
447     /*
448        If the device is currently in use, we won't release until it
449        is actually closed.
450     */
451     if (link->open) {
452 	DEBUG(1, "avma1_cs: release postponed, '%s' still open\n",
453 	      link->dev->dev_name);
454 	link->state |= DEV_STALE_CONFIG;
455 	return;
456     }
457 
458     /* no unregister function with hisax */
459     HiSax_closecard(local->node.minor);
460 
461     /* Unlink the device chain */
462     link->dev = NULL;
463 
464     /* Don't bother checking to see if these succeed or not */
465     CardServices(ReleaseConfiguration, link->handle);
466     CardServices(ReleaseIO, link->handle, &link->io);
467     CardServices(ReleaseIRQ, link->handle, &link->irq);
468     link->state &= ~DEV_CONFIG;
469 
470     if (link->state & DEV_STALE_LINK)
471 	avma1cs_detach(link);
472 
473 } /* avma1cs_release */
474 
475 /*======================================================================
476 
477     The card status event handler.  Mostly, this schedules other
478     stuff to run after an event is received.  A CARD_REMOVAL event
479     also sets some flags to discourage the net drivers from trying
480     to talk to the card any more.
481 
482     When a CARD_REMOVAL event is received, we immediately set a flag
483     to block future accesses to this device.  All the functions that
484     actually access the device should check this flag to make sure
485     the card is still present.
486 
487 ======================================================================*/
488 
avma1cs_event(event_t event,int priority,event_callback_args_t * args)489 static int avma1cs_event(event_t event, int priority,
490 			  event_callback_args_t *args)
491 {
492     dev_link_t *link = args->client_data;
493 
494     DEBUG(1, "avma1cs_event(0x%06x)\n", event);
495 
496     switch (event) {
497     case CS_EVENT_CARD_REMOVAL:
498 	link->state &= ~DEV_PRESENT;
499 	if (link->state & DEV_CONFIG) {
500 	    link->release.expires =  jiffies + HZ/20;
501 	    add_timer(&link->release);
502 	}
503 	break;
504     case CS_EVENT_CARD_INSERTION:
505 	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
506 	avma1cs_config(link);
507 	break;
508     case CS_EVENT_PM_SUSPEND:
509 	link->state |= DEV_SUSPEND;
510 	/* Fall through... */
511     case CS_EVENT_RESET_PHYSICAL:
512 	if (link->state & DEV_CONFIG)
513 	    CardServices(ReleaseConfiguration, link->handle);
514 	break;
515     case CS_EVENT_PM_RESUME:
516 	link->state &= ~DEV_SUSPEND;
517 	/* Fall through... */
518     case CS_EVENT_CARD_RESET:
519 	if (link->state & DEV_CONFIG)
520 	    CardServices(RequestConfiguration, link->handle, &link->conf);
521 	break;
522     }
523     return 0;
524 } /* avma1cs_event */
525 
526 /*====================================================================*/
527 
init_avma1_cs(void)528 static int __init init_avma1_cs(void)
529 {
530     servinfo_t serv;
531     DEBUG(0, "%s\n", version);
532     CardServices(GetCardServicesInfo, &serv);
533     if (serv.Revision != CS_RELEASE_CODE) {
534         printk(KERN_NOTICE "avma1_cs: Card Services release "
535                "does not match!\n");
536         return -1;
537     }
538     register_pccard_driver(&dev_info, &avma1cs_attach, &avma1cs_detach);
539     return 0;
540 }
541 
exit_avma1_cs(void)542 static void __exit exit_avma1_cs(void)
543 {
544     DEBUG(0, "avma1_cs: unloading\n");
545     unregister_pccard_driver(&dev_info);
546     while (dev_list != NULL)
547 	if (dev_list->state & DEV_CONFIG)
548 	    avma1cs_release((u_long)dev_list);
549         avma1cs_detach(dev_list);
550 }
551 
552 module_init(init_avma1_cs);
553 module_exit(exit_avma1_cs);
554