[PATCH] pcmcia: remove client services version
[deliverable/linux.git] / drivers / pcmcia / pcmcia_ioctl.c
1 /*
2 * pcmcia_ioctl.c -- ioctl interface for cardmgr and cardctl
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * The initial developer of the original code is David A. Hinds
9 * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
10 * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
11 *
12 * (C) 1999 David A. Hinds
13 * (C) 2003 - 2004 Dominik Brodowski
14 */
15
16 /*
17 * This file will go away soon.
18 */
19
20
21 #include <linux/config.h>
22 #include <linux/kernel.h>
23 #include <linux/module.h>
24 #include <linux/init.h>
25 #include <linux/major.h>
26 #include <linux/errno.h>
27 #include <linux/ioctl.h>
28 #include <linux/proc_fs.h>
29 #include <linux/poll.h>
30 #include <linux/pci.h>
31 #include <linux/workqueue.h>
32
33 #define IN_CARD_SERVICES
34 #include <pcmcia/version.h>
35 #include <pcmcia/cs_types.h>
36 #include <pcmcia/cs.h>
37 #include <pcmcia/cistpl.h>
38 #include <pcmcia/ds.h>
39 #include <pcmcia/ss.h>
40
41 #include "cs_internal.h"
42 #include "ds_internal.h"
43
44 static int major_dev = -1;
45
46
47 /* Device user information */
48 #define MAX_EVENTS 32
49 #define USER_MAGIC 0x7ea4
50 #define CHECK_USER(u) \
51 (((u) == NULL) || ((u)->user_magic != USER_MAGIC))
52
53 typedef struct user_info_t {
54 u_int user_magic;
55 int event_head, event_tail;
56 event_t event[MAX_EVENTS];
57 struct user_info_t *next;
58 struct pcmcia_socket *socket;
59 } user_info_t;
60
61
62 #ifdef DEBUG
63 extern int ds_pc_debug;
64 #define cs_socket_name(skt) ((skt)->dev.class_id)
65
66 #define ds_dbg(lvl, fmt, arg...) do { \
67 if (ds_pc_debug >= lvl) \
68 printk(KERN_DEBUG "ds: " fmt , ## arg); \
69 } while (0)
70 #else
71 #define ds_dbg(lvl, fmt, arg...) do { } while (0)
72 #endif
73
74
75 /* backwards-compatible accessing of driver --- by name! */
76
77 static struct pcmcia_driver * get_pcmcia_driver (dev_info_t *dev_info)
78 {
79 struct device_driver *drv;
80 struct pcmcia_driver *p_drv;
81
82 drv = driver_find((char *) dev_info, &pcmcia_bus_type);
83 if (!drv)
84 return NULL;
85
86 p_drv = container_of(drv, struct pcmcia_driver, drv);
87
88 return (p_drv);
89 }
90
91
92 #ifdef CONFIG_PROC_FS
93 static struct proc_dir_entry *proc_pccard = NULL;
94
95 static int proc_read_drivers_callback(struct device_driver *driver, void *d)
96 {
97 char **p = d;
98 struct pcmcia_driver *p_drv = container_of(driver,
99 struct pcmcia_driver, drv);
100
101 *p += sprintf(*p, "%-24.24s 1 %d\n", p_drv->drv.name,
102 #ifdef CONFIG_MODULE_UNLOAD
103 (p_drv->owner) ? module_refcount(p_drv->owner) : 1
104 #else
105 1
106 #endif
107 );
108 d = (void *) p;
109
110 return 0;
111 }
112
113 static int proc_read_drivers(char *buf, char **start, off_t pos,
114 int count, int *eof, void *data)
115 {
116 char *p = buf;
117
118 bus_for_each_drv(&pcmcia_bus_type, NULL,
119 (void *) &p, proc_read_drivers_callback);
120
121 return (p - buf);
122 }
123 #endif
124
125 /*======================================================================
126
127 These manage a ring buffer of events pending for one user process
128
129 ======================================================================*/
130
131
132 static int queue_empty(user_info_t *user)
133 {
134 return (user->event_head == user->event_tail);
135 }
136
137 static event_t get_queued_event(user_info_t *user)
138 {
139 user->event_tail = (user->event_tail+1) % MAX_EVENTS;
140 return user->event[user->event_tail];
141 }
142
143 static void queue_event(user_info_t *user, event_t event)
144 {
145 user->event_head = (user->event_head+1) % MAX_EVENTS;
146 if (user->event_head == user->event_tail)
147 user->event_tail = (user->event_tail+1) % MAX_EVENTS;
148 user->event[user->event_head] = event;
149 }
150
151 void handle_event(struct pcmcia_socket *s, event_t event)
152 {
153 user_info_t *user;
154 for (user = s->user; user; user = user->next)
155 queue_event(user, event);
156 wake_up_interruptible(&s->queue);
157 }
158
159
160 /*======================================================================
161
162 bind_request() and bind_device() are merged by now. Register_client()
163 is called right at the end of bind_request(), during the driver's
164 ->attach() call. Individual descriptions:
165
166 bind_request() connects a socket to a particular client driver.
167 It looks up the specified device ID in the list of registered
168 drivers, binds it to the socket, and tries to create an instance
169 of the device. unbind_request() deletes a driver instance.
170
171 Bind_device() associates a device driver with a particular socket.
172 It is normally called by Driver Services after it has identified
173 a newly inserted card. An instance of that driver will then be
174 eligible to register as a client of this socket.
175
176 Register_client() uses the dev_info_t handle to match the
177 caller with a socket. The driver must have already been bound
178 to a socket with bind_device() -- in fact, bind_device()
179 allocates the client structure that will be used.
180
181 ======================================================================*/
182
183 static int bind_request(struct pcmcia_socket *s, bind_info_t *bind_info)
184 {
185 struct pcmcia_driver *p_drv;
186 struct pcmcia_device *p_dev;
187 int ret = 0;
188 unsigned long flags;
189
190 s = pcmcia_get_socket(s);
191 if (!s)
192 return -EINVAL;
193
194 ds_dbg(2, "bind_request(%d, '%s')\n", s->sock,
195 (char *)bind_info->dev_info);
196
197 p_drv = get_pcmcia_driver(&bind_info->dev_info);
198 if (!p_drv) {
199 ret = -EINVAL;
200 goto err_put;
201 }
202
203 if (!try_module_get(p_drv->owner)) {
204 ret = -EINVAL;
205 goto err_put_driver;
206 }
207
208 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
209 list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
210 if (p_dev->func == bind_info->function) {
211 if ((p_dev->dev.driver == &p_drv->drv)) {
212 if (p_dev->cardmgr) {
213 /* if there's already a device
214 * registered, and it was registered
215 * by userspace before, we need to
216 * return the "instance". */
217 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
218 bind_info->instance = p_dev->instance;
219 ret = -EBUSY;
220 goto err_put_module;
221 } else {
222 /* the correct driver managed to bind
223 * itself magically to the correct
224 * device. */
225 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
226 p_dev->cardmgr = p_drv;
227 ret = 0;
228 goto err_put_module;
229 }
230 } else if (!p_dev->dev.driver) {
231 /* there's already a device available where
232 * no device has been bound to yet. So we don't
233 * need to register a device! */
234 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
235 goto rescan;
236 }
237 }
238 }
239 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
240
241 p_dev = pcmcia_device_add(s, bind_info->function);
242 if (!p_dev) {
243 ret = -EIO;
244 goto err_put_module;
245 }
246
247 rescan:
248 p_dev->cardmgr = p_drv;
249
250 /* if a driver is already running, we can abort */
251 if (p_dev->dev.driver)
252 goto err_put_module;
253
254 /*
255 * Prevent this racing with a card insertion.
256 */
257 down(&s->skt_sem);
258 bus_rescan_devices(&pcmcia_bus_type);
259 up(&s->skt_sem);
260
261 /* check whether the driver indeed matched. I don't care if this
262 * is racy or not, because it can only happen on cardmgr access
263 * paths...
264 */
265 if (!(p_dev->dev.driver == &p_drv->drv))
266 p_dev->cardmgr = NULL;
267
268 err_put_module:
269 module_put(p_drv->owner);
270 err_put_driver:
271 put_driver(&p_drv->drv);
272 err_put:
273 pcmcia_put_socket(s);
274
275 return (ret);
276 } /* bind_request */
277
278 #ifdef CONFIG_CARDBUS
279
280 static struct pci_bus *pcmcia_lookup_bus(struct pcmcia_socket *s)
281 {
282 if (!s || !(s->state & SOCKET_CARDBUS))
283 return NULL;
284
285 return s->cb_dev->subordinate;
286 }
287 #endif
288
289 static int get_device_info(struct pcmcia_socket *s, bind_info_t *bind_info, int first)
290 {
291 dev_node_t *node;
292 struct pcmcia_device *p_dev;
293 unsigned long flags;
294 int ret = 0;
295
296 #ifdef CONFIG_CARDBUS
297 /*
298 * Some unbelievably ugly code to associate the PCI cardbus
299 * device and its driver with the PCMCIA "bind" information.
300 */
301 {
302 struct pci_bus *bus;
303
304 bus = pcmcia_lookup_bus(s);
305 if (bus) {
306 struct list_head *list;
307 struct pci_dev *dev = NULL;
308
309 list = bus->devices.next;
310 while (list != &bus->devices) {
311 struct pci_dev *pdev = pci_dev_b(list);
312 list = list->next;
313
314 if (first) {
315 dev = pdev;
316 break;
317 }
318
319 /* Try to handle "next" here some way? */
320 }
321 if (dev && dev->driver) {
322 strlcpy(bind_info->name, dev->driver->name, DEV_NAME_LEN);
323 bind_info->major = 0;
324 bind_info->minor = 0;
325 bind_info->next = NULL;
326 return 0;
327 }
328 }
329 }
330 #endif
331
332 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
333 list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
334 if (p_dev->func == bind_info->function) {
335 p_dev = pcmcia_get_dev(p_dev);
336 if (!p_dev)
337 continue;
338 goto found;
339 }
340 }
341 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
342 return -ENODEV;
343
344 found:
345 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
346
347 if ((!p_dev->instance) ||
348 (p_dev->instance->state & DEV_CONFIG_PENDING)) {
349 ret = -EAGAIN;
350 goto err_put;
351 }
352
353 if (first)
354 node = p_dev->instance->dev;
355 else
356 for (node = p_dev->instance->dev; node; node = node->next)
357 if (node == bind_info->next)
358 break;
359 if (!node) {
360 ret = -ENODEV;
361 goto err_put;
362 }
363
364 strlcpy(bind_info->name, node->dev_name, DEV_NAME_LEN);
365 bind_info->major = node->major;
366 bind_info->minor = node->minor;
367 bind_info->next = node->next;
368
369 err_put:
370 pcmcia_put_dev(p_dev);
371 return (ret);
372 } /* get_device_info */
373
374
375 static int ds_open(struct inode *inode, struct file *file)
376 {
377 socket_t i = iminor(inode);
378 struct pcmcia_socket *s;
379 user_info_t *user;
380
381 ds_dbg(0, "ds_open(socket %d)\n", i);
382
383 s = pcmcia_get_socket_by_nr(i);
384 if (!s)
385 return -ENODEV;
386 s = pcmcia_get_socket(s);
387 if (!s)
388 return -ENODEV;
389
390 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
391 if (s->pcmcia_state.busy) {
392 pcmcia_put_socket(s);
393 return -EBUSY;
394 }
395 else
396 s->pcmcia_state.busy = 1;
397 }
398
399 user = kmalloc(sizeof(user_info_t), GFP_KERNEL);
400 if (!user) {
401 pcmcia_put_socket(s);
402 return -ENOMEM;
403 }
404 user->event_tail = user->event_head = 0;
405 user->next = s->user;
406 user->user_magic = USER_MAGIC;
407 user->socket = s;
408 s->user = user;
409 file->private_data = user;
410
411 if (s->pcmcia_state.present)
412 queue_event(user, CS_EVENT_CARD_INSERTION);
413 return 0;
414 } /* ds_open */
415
416 /*====================================================================*/
417
418 static int ds_release(struct inode *inode, struct file *file)
419 {
420 struct pcmcia_socket *s;
421 user_info_t *user, **link;
422
423 ds_dbg(0, "ds_release(socket %d)\n", iminor(inode));
424
425 user = file->private_data;
426 if (CHECK_USER(user))
427 goto out;
428
429 s = user->socket;
430
431 /* Unlink user data structure */
432 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
433 s->pcmcia_state.busy = 0;
434 }
435 file->private_data = NULL;
436 for (link = &s->user; *link; link = &(*link)->next)
437 if (*link == user) break;
438 if (link == NULL)
439 goto out;
440 *link = user->next;
441 user->user_magic = 0;
442 kfree(user);
443 pcmcia_put_socket(s);
444 out:
445 return 0;
446 } /* ds_release */
447
448 /*====================================================================*/
449
450 static ssize_t ds_read(struct file *file, char __user *buf,
451 size_t count, loff_t *ppos)
452 {
453 struct pcmcia_socket *s;
454 user_info_t *user;
455 int ret;
456
457 ds_dbg(2, "ds_read(socket %d)\n", iminor(file->f_dentry->d_inode));
458
459 if (count < 4)
460 return -EINVAL;
461
462 user = file->private_data;
463 if (CHECK_USER(user))
464 return -EIO;
465
466 s = user->socket;
467 if (s->pcmcia_state.dead)
468 return -EIO;
469
470 ret = wait_event_interruptible(s->queue, !queue_empty(user));
471 if (ret == 0)
472 ret = put_user(get_queued_event(user), (int __user *)buf) ? -EFAULT : 4;
473
474 return ret;
475 } /* ds_read */
476
477 /*====================================================================*/
478
479 static ssize_t ds_write(struct file *file, const char __user *buf,
480 size_t count, loff_t *ppos)
481 {
482 ds_dbg(2, "ds_write(socket %d)\n", iminor(file->f_dentry->d_inode));
483
484 if (count != 4)
485 return -EINVAL;
486 if ((file->f_flags & O_ACCMODE) == O_RDONLY)
487 return -EBADF;
488
489 return -EIO;
490 } /* ds_write */
491
492 /*====================================================================*/
493
494 /* No kernel lock - fine */
495 static u_int ds_poll(struct file *file, poll_table *wait)
496 {
497 struct pcmcia_socket *s;
498 user_info_t *user;
499
500 ds_dbg(2, "ds_poll(socket %d)\n", iminor(file->f_dentry->d_inode));
501
502 user = file->private_data;
503 if (CHECK_USER(user))
504 return POLLERR;
505 s = user->socket;
506 /*
507 * We don't check for a dead socket here since that
508 * will send cardmgr into an endless spin.
509 */
510 poll_wait(file, &s->queue, wait);
511 if (!queue_empty(user))
512 return POLLIN | POLLRDNORM;
513 return 0;
514 } /* ds_poll */
515
516 /*====================================================================*/
517
518 extern int pcmcia_adjust_resource_info(adjust_t *adj);
519
520 static int ds_ioctl(struct inode * inode, struct file * file,
521 u_int cmd, u_long arg)
522 {
523 struct pcmcia_socket *s;
524 void __user *uarg = (char __user *)arg;
525 u_int size;
526 int ret, err;
527 ds_ioctl_arg_t *buf;
528 user_info_t *user;
529
530 ds_dbg(2, "ds_ioctl(socket %d, %#x, %#lx)\n", iminor(inode), cmd, arg);
531
532 user = file->private_data;
533 if (CHECK_USER(user))
534 return -EIO;
535
536 s = user->socket;
537 if (s->pcmcia_state.dead)
538 return -EIO;
539
540 size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
541 if (size > sizeof(ds_ioctl_arg_t)) return -EINVAL;
542
543 /* Permission check */
544 if (!(cmd & IOC_OUT) && !capable(CAP_SYS_ADMIN))
545 return -EPERM;
546
547 if (cmd & IOC_IN) {
548 if (!access_ok(VERIFY_READ, uarg, size)) {
549 ds_dbg(3, "ds_ioctl(): verify_read = %d\n", -EFAULT);
550 return -EFAULT;
551 }
552 }
553 if (cmd & IOC_OUT) {
554 if (!access_ok(VERIFY_WRITE, uarg, size)) {
555 ds_dbg(3, "ds_ioctl(): verify_write = %d\n", -EFAULT);
556 return -EFAULT;
557 }
558 }
559 buf = kmalloc(sizeof(ds_ioctl_arg_t), GFP_KERNEL);
560 if (!buf)
561 return -ENOMEM;
562
563 err = ret = 0;
564
565 if (cmd & IOC_IN) __copy_from_user((char *)buf, uarg, size);
566
567 switch (cmd) {
568 case DS_ADJUST_RESOURCE_INFO:
569 ret = pcmcia_adjust_resource_info(&buf->adjust);
570 break;
571 case DS_GET_CONFIGURATION_INFO:
572 if (buf->config.Function &&
573 (buf->config.Function >= s->functions))
574 ret = CS_BAD_ARGS;
575 else
576 ret = pccard_get_configuration_info(s,
577 buf->config.Function, &buf->config);
578 break;
579 case DS_GET_FIRST_TUPLE:
580 down(&s->skt_sem);
581 pcmcia_validate_mem(s);
582 up(&s->skt_sem);
583 ret = pccard_get_first_tuple(s, BIND_FN_ALL, &buf->tuple);
584 break;
585 case DS_GET_NEXT_TUPLE:
586 ret = pccard_get_next_tuple(s, BIND_FN_ALL, &buf->tuple);
587 break;
588 case DS_GET_TUPLE_DATA:
589 buf->tuple.TupleData = buf->tuple_parse.data;
590 buf->tuple.TupleDataMax = sizeof(buf->tuple_parse.data);
591 ret = pccard_get_tuple_data(s, &buf->tuple);
592 break;
593 case DS_PARSE_TUPLE:
594 buf->tuple.TupleData = buf->tuple_parse.data;
595 ret = pccard_parse_tuple(&buf->tuple, &buf->tuple_parse.parse);
596 break;
597 case DS_RESET_CARD:
598 ret = pccard_reset_card(s);
599 break;
600 case DS_GET_STATUS:
601 if (buf->status.Function &&
602 (buf->status.Function >= s->functions))
603 ret = CS_BAD_ARGS;
604 else
605 ret = pccard_get_status(s, buf->status.Function, &buf->status);
606 break;
607 case DS_VALIDATE_CIS:
608 down(&s->skt_sem);
609 pcmcia_validate_mem(s);
610 up(&s->skt_sem);
611 ret = pccard_validate_cis(s, BIND_FN_ALL, &buf->cisinfo);
612 break;
613 case DS_SUSPEND_CARD:
614 ret = pcmcia_suspend_card(s);
615 break;
616 case DS_RESUME_CARD:
617 ret = pcmcia_resume_card(s);
618 break;
619 case DS_EJECT_CARD:
620 err = pcmcia_eject_card(s);
621 break;
622 case DS_INSERT_CARD:
623 err = pcmcia_insert_card(s);
624 break;
625 case DS_ACCESS_CONFIGURATION_REGISTER:
626 if ((buf->conf_reg.Action == CS_WRITE) && !capable(CAP_SYS_ADMIN)) {
627 err = -EPERM;
628 goto free_out;
629 }
630 if (buf->conf_reg.Function &&
631 (buf->conf_reg.Function >= s->functions))
632 ret = CS_BAD_ARGS;
633 else
634 ret = pccard_access_configuration_register(s,
635 buf->conf_reg.Function, &buf->conf_reg);
636 break;
637 case DS_GET_FIRST_REGION:
638 case DS_GET_NEXT_REGION:
639 case DS_BIND_MTD:
640 if (!capable(CAP_SYS_ADMIN)) {
641 err = -EPERM;
642 goto free_out;
643 } else {
644 static int printed = 0;
645 if (!printed) {
646 printk(KERN_WARNING "2.6. kernels use pcmciamtd instead of memory_cs.c and do not require special\n");
647 printk(KERN_WARNING "MTD handling any more.\n");
648 printed++;
649 }
650 }
651 err = -EINVAL;
652 goto free_out;
653 break;
654 case DS_GET_FIRST_WINDOW:
655 ret = pcmcia_get_window(s, &buf->win_info.handle, 0,
656 &buf->win_info.window);
657 break;
658 case DS_GET_NEXT_WINDOW:
659 ret = pcmcia_get_window(s, &buf->win_info.handle,
660 buf->win_info.handle->index + 1, &buf->win_info.window);
661 break;
662 case DS_GET_MEM_PAGE:
663 ret = pcmcia_get_mem_page(buf->win_info.handle,
664 &buf->win_info.map);
665 break;
666 case DS_REPLACE_CIS:
667 ret = pcmcia_replace_cis(s, &buf->cisdump);
668 break;
669 case DS_BIND_REQUEST:
670 if (!capable(CAP_SYS_ADMIN)) {
671 err = -EPERM;
672 goto free_out;
673 }
674 err = bind_request(s, &buf->bind_info);
675 break;
676 case DS_GET_DEVICE_INFO:
677 err = get_device_info(s, &buf->bind_info, 1);
678 break;
679 case DS_GET_NEXT_DEVICE:
680 err = get_device_info(s, &buf->bind_info, 0);
681 break;
682 case DS_UNBIND_REQUEST:
683 err = 0;
684 break;
685 default:
686 err = -EINVAL;
687 }
688
689 if ((err == 0) && (ret != CS_SUCCESS)) {
690 ds_dbg(2, "ds_ioctl: ret = %d\n", ret);
691 switch (ret) {
692 case CS_BAD_SOCKET: case CS_NO_CARD:
693 err = -ENODEV; break;
694 case CS_BAD_ARGS: case CS_BAD_ATTRIBUTE: case CS_BAD_IRQ:
695 case CS_BAD_TUPLE:
696 err = -EINVAL; break;
697 case CS_IN_USE:
698 err = -EBUSY; break;
699 case CS_OUT_OF_RESOURCE:
700 err = -ENOSPC; break;
701 case CS_NO_MORE_ITEMS:
702 err = -ENODATA; break;
703 case CS_UNSUPPORTED_FUNCTION:
704 err = -ENOSYS; break;
705 default:
706 err = -EIO; break;
707 }
708 }
709
710 if (cmd & IOC_OUT) {
711 if (__copy_to_user(uarg, (char *)buf, size))
712 err = -EFAULT;
713 }
714
715 free_out:
716 kfree(buf);
717 return err;
718 } /* ds_ioctl */
719
720 /*====================================================================*/
721
722 static struct file_operations ds_fops = {
723 .owner = THIS_MODULE,
724 .open = ds_open,
725 .release = ds_release,
726 .ioctl = ds_ioctl,
727 .read = ds_read,
728 .write = ds_write,
729 .poll = ds_poll,
730 };
731
732 void __init pcmcia_setup_ioctl(void) {
733 int i;
734
735 /* Set up character device for user mode clients */
736 i = register_chrdev(0, "pcmcia", &ds_fops);
737 if (i < 0)
738 printk(KERN_NOTICE "unable to find a free device # for "
739 "Driver Services (error=%d)\n", i);
740 else
741 major_dev = i;
742
743 #ifdef CONFIG_PROC_FS
744 proc_pccard = proc_mkdir("pccard", proc_bus);
745 if (proc_pccard)
746 create_proc_read_entry("drivers",0,proc_pccard,proc_read_drivers,NULL);
747 #endif
748 }
749
750
751 void __exit pcmcia_cleanup_ioctl(void) {
752 #ifdef CONFIG_PROC_FS
753 if (proc_pccard) {
754 remove_proc_entry("drivers", proc_pccard);
755 remove_proc_entry("pccard", proc_bus);
756 }
757 #endif
758 if (major_dev != -1)
759 unregister_chrdev(major_dev, "pcmcia");
760 }
This page took 0.069089 seconds and 5 git commands to generate.