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