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