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