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