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