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