]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/pcmcia/pcmcia_ioctl.c
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[linux-2.6-omap-h63xx.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/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         struct pcmcia_driver *p_drv;
308         unsigned long flags;
309         int ret = 0;
310
311 #ifdef CONFIG_CARDBUS
312         /*
313          * Some unbelievably ugly code to associate the PCI cardbus
314          * device and its driver with the PCMCIA "bind" information.
315          */
316         {
317                 struct pci_bus *bus;
318
319                 bus = pcmcia_lookup_bus(s);
320                 if (bus) {
321                         struct list_head *list;
322                         struct pci_dev *dev = NULL;
323
324                         list = bus->devices.next;
325                         while (list != &bus->devices) {
326                                 struct pci_dev *pdev = pci_dev_b(list);
327                                 list = list->next;
328
329                                 if (first) {
330                                         dev = pdev;
331                                         break;
332                                 }
333
334                                 /* Try to handle "next" here some way? */
335                         }
336                         if (dev && dev->driver) {
337                                 strlcpy(bind_info->name, dev->driver->name, DEV_NAME_LEN);
338                                 bind_info->major = 0;
339                                 bind_info->minor = 0;
340                                 bind_info->next = NULL;
341                                 return 0;
342                         }
343                 }
344         }
345 #endif
346
347         spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
348         list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
349                 if (p_dev->func == bind_info->function) {
350                         p_dev = pcmcia_get_dev(p_dev);
351                         if (!p_dev)
352                                 continue;
353                         goto found;
354                 }
355         }
356         spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
357         return -ENODEV;
358
359  found:
360         spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
361
362         p_drv = to_pcmcia_drv(p_dev->dev.driver);
363         if (p_drv && !p_dev->_locked) {
364                 ret = -EAGAIN;
365                 goto err_put;
366         }
367
368         if (first)
369                 node = p_dev->dev_node;
370         else
371                 for (node = p_dev->dev_node; node; node = node->next)
372                         if (node == bind_info->next)
373                                 break;
374         if (!node) {
375                 ret = -ENODEV;
376                 goto err_put;
377         }
378
379         strlcpy(bind_info->name, node->dev_name, DEV_NAME_LEN);
380         bind_info->major = node->major;
381         bind_info->minor = node->minor;
382         bind_info->next = node->next;
383
384  err_put:
385         pcmcia_put_dev(p_dev);
386         return (ret);
387 } /* get_device_info */
388
389
390 static int ds_open(struct inode *inode, struct file *file)
391 {
392     socket_t i = iminor(inode);
393     struct pcmcia_socket *s;
394     user_info_t *user;
395     static int warning_printed = 0;
396
397     ds_dbg(0, "ds_open(socket %d)\n", i);
398
399     s = pcmcia_get_socket_by_nr(i);
400     if (!s)
401             return -ENODEV;
402     s = pcmcia_get_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_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_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 (!warning_printed) {
428             printk(KERN_INFO "pcmcia: Detected deprecated PCMCIA ioctl "
429                         "usage from process: %s.\n", current->comm);
430             printk(KERN_INFO "pcmcia: This interface will soon be removed from "
431                         "the kernel; please expect breakage unless you upgrade "
432                         "to new tools.\n");
433             printk(KERN_INFO "pcmcia: see http://www.kernel.org/pub/linux/"
434                         "utils/kernel/pcmcia/pcmcia.html for details.\n");
435             warning_printed = 1;
436     }
437
438     if (s->pcmcia_state.present)
439         queue_event(user, CS_EVENT_CARD_INSERTION);
440     return 0;
441 } /* ds_open */
442
443 /*====================================================================*/
444
445 static int ds_release(struct inode *inode, struct file *file)
446 {
447     struct pcmcia_socket *s;
448     user_info_t *user, **link;
449
450     ds_dbg(0, "ds_release(socket %d)\n", iminor(inode));
451
452     user = file->private_data;
453     if (CHECK_USER(user))
454         goto out;
455
456     s = user->socket;
457
458     /* Unlink user data structure */
459     if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
460         s->pcmcia_state.busy = 0;
461     }
462     file->private_data = NULL;
463     for (link = &s->user; *link; link = &(*link)->next)
464         if (*link == user) break;
465     if (link == NULL)
466         goto out;
467     *link = user->next;
468     user->user_magic = 0;
469     kfree(user);
470     pcmcia_put_socket(s);
471 out:
472     return 0;
473 } /* ds_release */
474
475 /*====================================================================*/
476
477 static ssize_t ds_read(struct file *file, char __user *buf,
478                        size_t count, loff_t *ppos)
479 {
480     struct pcmcia_socket *s;
481     user_info_t *user;
482     int ret;
483
484     ds_dbg(2, "ds_read(socket %d)\n", iminor(file->f_dentry->d_inode));
485
486     if (count < 4)
487         return -EINVAL;
488
489     user = file->private_data;
490     if (CHECK_USER(user))
491         return -EIO;
492
493     s = user->socket;
494     if (s->pcmcia_state.dead)
495         return -EIO;
496
497     ret = wait_event_interruptible(s->queue, !queue_empty(user));
498     if (ret == 0)
499         ret = put_user(get_queued_event(user), (int __user *)buf) ? -EFAULT : 4;
500
501     return ret;
502 } /* ds_read */
503
504 /*====================================================================*/
505
506 static ssize_t ds_write(struct file *file, const char __user *buf,
507                         size_t count, loff_t *ppos)
508 {
509     ds_dbg(2, "ds_write(socket %d)\n", iminor(file->f_dentry->d_inode));
510
511     if (count != 4)
512         return -EINVAL;
513     if ((file->f_flags & O_ACCMODE) == O_RDONLY)
514         return -EBADF;
515
516     return -EIO;
517 } /* ds_write */
518
519 /*====================================================================*/
520
521 /* No kernel lock - fine */
522 static u_int ds_poll(struct file *file, poll_table *wait)
523 {
524     struct pcmcia_socket *s;
525     user_info_t *user;
526
527     ds_dbg(2, "ds_poll(socket %d)\n", iminor(file->f_dentry->d_inode));
528
529     user = file->private_data;
530     if (CHECK_USER(user))
531         return POLLERR;
532     s = user->socket;
533     /*
534      * We don't check for a dead socket here since that
535      * will send cardmgr into an endless spin.
536      */
537     poll_wait(file, &s->queue, wait);
538     if (!queue_empty(user))
539         return POLLIN | POLLRDNORM;
540     return 0;
541 } /* ds_poll */
542
543 /*====================================================================*/
544
545 extern int pcmcia_adjust_resource_info(adjust_t *adj);
546
547 static int ds_ioctl(struct inode * inode, struct file * file,
548                     u_int cmd, u_long arg)
549 {
550     struct pcmcia_socket *s;
551     void __user *uarg = (char __user *)arg;
552     u_int size;
553     int ret, err;
554     ds_ioctl_arg_t *buf;
555     user_info_t *user;
556
557     ds_dbg(2, "ds_ioctl(socket %d, %#x, %#lx)\n", iminor(inode), cmd, arg);
558
559     user = file->private_data;
560     if (CHECK_USER(user))
561         return -EIO;
562
563     s = user->socket;
564     if (s->pcmcia_state.dead)
565         return -EIO;
566
567     size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
568     if (size > sizeof(ds_ioctl_arg_t)) return -EINVAL;
569
570     /* Permission check */
571     if (!(cmd & IOC_OUT) && !capable(CAP_SYS_ADMIN))
572         return -EPERM;
573
574     if (cmd & IOC_IN) {
575         if (!access_ok(VERIFY_READ, uarg, size)) {
576             ds_dbg(3, "ds_ioctl(): verify_read = %d\n", -EFAULT);
577             return -EFAULT;
578         }
579     }
580     if (cmd & IOC_OUT) {
581         if (!access_ok(VERIFY_WRITE, uarg, size)) {
582             ds_dbg(3, "ds_ioctl(): verify_write = %d\n", -EFAULT);
583             return -EFAULT;
584         }
585     }
586     buf = kmalloc(sizeof(ds_ioctl_arg_t), GFP_KERNEL);
587     if (!buf)
588         return -ENOMEM;
589
590     err = ret = 0;
591
592     if (cmd & IOC_IN) __copy_from_user((char *)buf, uarg, size);
593
594     switch (cmd) {
595     case DS_ADJUST_RESOURCE_INFO:
596         ret = pcmcia_adjust_resource_info(&buf->adjust);
597         break;
598     case DS_GET_CONFIGURATION_INFO:
599         if (buf->config.Function &&
600            (buf->config.Function >= s->functions))
601             ret = CS_BAD_ARGS;
602         else {
603             struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->config.Function);
604             if (p_dev == NULL)
605                     ret = CS_BAD_ARGS;
606             else {
607                     ret = pccard_get_configuration_info(s, p_dev, &buf->config);
608                     pcmcia_put_dev(p_dev);
609             }
610         }
611         break;
612     case DS_GET_FIRST_TUPLE:
613         mutex_lock(&s->skt_mutex);
614         pcmcia_validate_mem(s);
615         mutex_unlock(&s->skt_mutex);
616         ret = pccard_get_first_tuple(s, BIND_FN_ALL, &buf->tuple);
617         break;
618     case DS_GET_NEXT_TUPLE:
619         ret = pccard_get_next_tuple(s, BIND_FN_ALL, &buf->tuple);
620         break;
621     case DS_GET_TUPLE_DATA:
622         buf->tuple.TupleData = buf->tuple_parse.data;
623         buf->tuple.TupleDataMax = sizeof(buf->tuple_parse.data);
624         ret = pccard_get_tuple_data(s, &buf->tuple);
625         break;
626     case DS_PARSE_TUPLE:
627         buf->tuple.TupleData = buf->tuple_parse.data;
628         ret = pccard_parse_tuple(&buf->tuple, &buf->tuple_parse.parse);
629         break;
630     case DS_RESET_CARD:
631         ret = pccard_reset_card(s);
632         break;
633     case DS_GET_STATUS:
634             if (buf->status.Function &&
635                 (buf->status.Function >= s->functions))
636                     ret = CS_BAD_ARGS;
637             else {
638                     struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->status.Function);
639                     if (p_dev == NULL)
640                             ret = CS_BAD_ARGS;
641                     else {
642                             ret = pccard_get_status(s, p_dev, &buf->status);
643                             pcmcia_put_dev(p_dev);
644                     }
645             }
646             break;
647     case DS_VALIDATE_CIS:
648         mutex_lock(&s->skt_mutex);
649         pcmcia_validate_mem(s);
650         mutex_unlock(&s->skt_mutex);
651         ret = pccard_validate_cis(s, BIND_FN_ALL, &buf->cisinfo);
652         break;
653     case DS_SUSPEND_CARD:
654         ret = pcmcia_suspend_card(s);
655         break;
656     case DS_RESUME_CARD:
657         ret = pcmcia_resume_card(s);
658         break;
659     case DS_EJECT_CARD:
660         err = pcmcia_eject_card(s);
661         break;
662     case DS_INSERT_CARD:
663         err = pcmcia_insert_card(s);
664         break;
665     case DS_ACCESS_CONFIGURATION_REGISTER:
666         if ((buf->conf_reg.Action == CS_WRITE) && !capable(CAP_SYS_ADMIN)) {
667             err = -EPERM;
668             goto free_out;
669         }
670
671         ret = CS_BAD_ARGS;
672
673         if (!(buf->conf_reg.Function &&
674              (buf->conf_reg.Function >= s->functions))) {
675                 struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->conf_reg.Function);
676                 if (p_dev) {
677                         ret = pcmcia_access_configuration_register(p_dev, &buf->conf_reg);
678                         pcmcia_put_dev(p_dev);
679                 }
680         }
681         break;
682     case DS_GET_FIRST_REGION:
683     case DS_GET_NEXT_REGION:
684     case DS_BIND_MTD:
685         if (!capable(CAP_SYS_ADMIN)) {
686                 err = -EPERM;
687                 goto free_out;
688         } else {
689                 static int printed = 0;
690                 if (!printed) {
691                         printk(KERN_WARNING "2.6. kernels use pcmciamtd instead of memory_cs.c and do not require special\n");
692                         printk(KERN_WARNING "MTD handling any more.\n");
693                         printed++;
694                 }
695         }
696         err = -EINVAL;
697         goto free_out;
698         break;
699     case DS_GET_FIRST_WINDOW:
700         ret = pcmcia_get_window(s, &buf->win_info.handle, 0,
701                         &buf->win_info.window);
702         break;
703     case DS_GET_NEXT_WINDOW:
704         ret = pcmcia_get_window(s, &buf->win_info.handle,
705                         buf->win_info.handle->index + 1, &buf->win_info.window);
706         break;
707     case DS_GET_MEM_PAGE:
708         ret = pcmcia_get_mem_page(buf->win_info.handle,
709                            &buf->win_info.map);
710         break;
711     case DS_REPLACE_CIS:
712         ret = pcmcia_replace_cis(s, &buf->cisdump);
713         break;
714     case DS_BIND_REQUEST:
715         if (!capable(CAP_SYS_ADMIN)) {
716                 err = -EPERM;
717                 goto free_out;
718         }
719         err = bind_request(s, &buf->bind_info);
720         break;
721     case DS_GET_DEVICE_INFO:
722         err = get_device_info(s, &buf->bind_info, 1);
723         break;
724     case DS_GET_NEXT_DEVICE:
725         err = get_device_info(s, &buf->bind_info, 0);
726         break;
727     case DS_UNBIND_REQUEST:
728         err = 0;
729         break;
730     default:
731         err = -EINVAL;
732     }
733
734     if ((err == 0) && (ret != CS_SUCCESS)) {
735         ds_dbg(2, "ds_ioctl: ret = %d\n", ret);
736         switch (ret) {
737         case CS_BAD_SOCKET: case CS_NO_CARD:
738             err = -ENODEV; break;
739         case CS_BAD_ARGS: case CS_BAD_ATTRIBUTE: case CS_BAD_IRQ:
740         case CS_BAD_TUPLE:
741             err = -EINVAL; break;
742         case CS_IN_USE:
743             err = -EBUSY; break;
744         case CS_OUT_OF_RESOURCE:
745             err = -ENOSPC; break;
746         case CS_NO_MORE_ITEMS:
747             err = -ENODATA; break;
748         case CS_UNSUPPORTED_FUNCTION:
749             err = -ENOSYS; break;
750         default:
751             err = -EIO; break;
752         }
753     }
754
755     if (cmd & IOC_OUT) {
756         if (__copy_to_user(uarg, (char *)buf, size))
757             err = -EFAULT;
758     }
759
760 free_out:
761     kfree(buf);
762     return err;
763 } /* ds_ioctl */
764
765 /*====================================================================*/
766
767 static struct file_operations ds_fops = {
768         .owner          = THIS_MODULE,
769         .open           = ds_open,
770         .release        = ds_release,
771         .ioctl          = ds_ioctl,
772         .read           = ds_read,
773         .write          = ds_write,
774         .poll           = ds_poll,
775 };
776
777 void __init pcmcia_setup_ioctl(void) {
778         int i;
779
780         /* Set up character device for user mode clients */
781         i = register_chrdev(0, "pcmcia", &ds_fops);
782         if (i < 0)
783                 printk(KERN_NOTICE "unable to find a free device # for "
784                        "Driver Services (error=%d)\n", i);
785         else
786                 major_dev = i;
787
788 #ifdef CONFIG_PROC_FS
789         proc_pccard = proc_mkdir("pccard", proc_bus);
790         if (proc_pccard)
791                 create_proc_read_entry("drivers",0,proc_pccard,proc_read_drivers,NULL);
792 #endif
793 }
794
795
796 void __exit pcmcia_cleanup_ioctl(void) {
797 #ifdef CONFIG_PROC_FS
798         if (proc_pccard) {
799                 remove_proc_entry("drivers", proc_pccard);
800                 remove_proc_entry("pccard", proc_bus);
801         }
802 #endif
803         if (major_dev != -1)
804                 unregister_chrdev(major_dev, "pcmcia");
805 }