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