pcmcia: kill IN_CARD_SERVICES
[linux-2.6.git] / drivers / pcmcia / pcmcia_ioctl.c
blob2d05210195362a069d377a62531313016ce93d36
1 /*
2 * pcmcia_ioctl.c -- ioctl interface for cardmgr and cardctl
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.
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.
12 * (C) 1999 David A. Hinds
13 * (C) 2003 - 2004 Dominik Brodowski
17 * This file will go away soon.
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>
32 #include <pcmcia/cs_types.h>
33 #include <pcmcia/cs.h>
34 #include <pcmcia/cistpl.h>
35 #include <pcmcia/ds.h>
36 #include <pcmcia/ss.h>
38 #include "cs_internal.h"
39 #include "ds_internal.h"
41 static int major_dev = -1;
44 /* Device user information */
45 #define MAX_EVENTS 32
46 #define USER_MAGIC 0x7ea4
47 #define CHECK_USER(u) \
48 (((u) == NULL) || ((u)->user_magic != USER_MAGIC))
50 typedef struct user_info_t {
51 u_int user_magic;
52 int event_head, event_tail;
53 event_t event[MAX_EVENTS];
54 struct user_info_t *next;
55 struct pcmcia_socket *socket;
56 } user_info_t;
59 #ifdef DEBUG
60 extern int ds_pc_debug;
62 #define ds_dbg(lvl, fmt, arg...) do { \
63 if (ds_pc_debug >= lvl) \
64 printk(KERN_DEBUG "ds: " fmt , ## arg); \
65 } while (0)
66 #else
67 #define ds_dbg(lvl, fmt, arg...) do { } while (0)
68 #endif
70 static struct pcmcia_device *get_pcmcia_device(struct pcmcia_socket *s,
71 unsigned int function)
73 struct pcmcia_device *p_dev = NULL;
74 unsigned long flags;
76 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
77 list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
78 if (p_dev->func == function) {
79 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
80 return pcmcia_get_dev(p_dev);
83 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
84 return NULL;
87 /* backwards-compatible accessing of driver --- by name! */
89 static struct pcmcia_driver *get_pcmcia_driver(dev_info_t *dev_info)
91 struct device_driver *drv;
92 struct pcmcia_driver *p_drv;
94 drv = driver_find((char *) dev_info, &pcmcia_bus_type);
95 if (!drv)
96 return NULL;
98 p_drv = container_of(drv, struct pcmcia_driver, drv);
100 return (p_drv);
104 #ifdef CONFIG_PROC_FS
105 static struct proc_dir_entry *proc_pccard = NULL;
107 static int proc_read_drivers_callback(struct device_driver *driver, void *d)
109 char **p = d;
110 struct pcmcia_driver *p_drv = container_of(driver,
111 struct pcmcia_driver, drv);
113 *p += sprintf(*p, "%-24.24s 1 %d\n", p_drv->drv.name,
114 #ifdef CONFIG_MODULE_UNLOAD
115 (p_drv->owner) ? module_refcount(p_drv->owner) : 1
116 #else
118 #endif
120 d = (void *) p;
122 return 0;
125 static int proc_read_drivers(char *buf, char **start, off_t pos,
126 int count, int *eof, void *data)
128 char *p = buf;
129 int rc;
131 rc = bus_for_each_drv(&pcmcia_bus_type, NULL,
132 (void *) &p, proc_read_drivers_callback);
133 if (rc < 0)
134 return rc;
136 return (p - buf);
138 #endif
141 #ifdef CONFIG_PCMCIA_PROBE
143 static int adjust_irq(struct pcmcia_socket *s, adjust_t *adj)
145 int irq;
146 u32 mask;
148 irq = adj->resource.irq.IRQ;
149 if ((irq < 0) || (irq > 15))
150 return CS_BAD_IRQ;
152 if (adj->Action != REMOVE_MANAGED_RESOURCE)
153 return 0;
155 mask = 1 << irq;
157 if (!(s->irq_mask & mask))
158 return 0;
160 s->irq_mask &= ~mask;
162 return 0;
165 #else
167 static inline int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) {
168 return CS_SUCCESS;
171 #endif
173 static int pcmcia_adjust_resource_info(adjust_t *adj)
175 struct pcmcia_socket *s;
176 int ret = CS_UNSUPPORTED_FUNCTION;
177 unsigned long flags;
179 down_read(&pcmcia_socket_list_rwsem);
180 list_for_each_entry(s, &pcmcia_socket_list, socket_list) {
182 if (adj->Resource == RES_IRQ)
183 ret = adjust_irq(s, adj);
185 else if (s->resource_ops->add_io) {
186 unsigned long begin, end;
188 /* you can't use the old interface if the new
189 * one was used before */
190 spin_lock_irqsave(&s->lock, flags);
191 if ((s->resource_setup_new) &&
192 !(s->resource_setup_old)) {
193 spin_unlock_irqrestore(&s->lock, flags);
194 continue;
195 } else if (!(s->resource_setup_old))
196 s->resource_setup_old = 1;
197 spin_unlock_irqrestore(&s->lock, flags);
199 switch (adj->Resource) {
200 case RES_MEMORY_RANGE:
201 begin = adj->resource.memory.Base;
202 end = adj->resource.memory.Base + adj->resource.memory.Size - 1;
203 if (s->resource_ops->add_mem)
204 ret =s->resource_ops->add_mem(s, adj->Action, begin, end);
205 case RES_IO_RANGE:
206 begin = adj->resource.io.BasePort;
207 end = adj->resource.io.BasePort + adj->resource.io.NumPorts - 1;
208 if (s->resource_ops->add_io)
209 ret = s->resource_ops->add_io(s, adj->Action, begin, end);
211 if (!ret) {
212 /* as there's no way we know this is the
213 * last call to adjust_resource_info, we
214 * always need to assume this is the latest
215 * one... */
216 spin_lock_irqsave(&s->lock, flags);
217 s->resource_setup_done = 1;
218 spin_unlock_irqrestore(&s->lock, flags);
222 up_read(&pcmcia_socket_list_rwsem);
224 return (ret);
228 /*======================================================================
230 These manage a ring buffer of events pending for one user process
232 ======================================================================*/
235 static int queue_empty(user_info_t *user)
237 return (user->event_head == user->event_tail);
240 static event_t get_queued_event(user_info_t *user)
242 user->event_tail = (user->event_tail+1) % MAX_EVENTS;
243 return user->event[user->event_tail];
246 static void queue_event(user_info_t *user, event_t event)
248 user->event_head = (user->event_head+1) % MAX_EVENTS;
249 if (user->event_head == user->event_tail)
250 user->event_tail = (user->event_tail+1) % MAX_EVENTS;
251 user->event[user->event_head] = event;
254 void handle_event(struct pcmcia_socket *s, event_t event)
256 user_info_t *user;
257 for (user = s->user; user; user = user->next)
258 queue_event(user, event);
259 wake_up_interruptible(&s->queue);
263 /*======================================================================
265 bind_request() and bind_device() are merged by now. Register_client()
266 is called right at the end of bind_request(), during the driver's
267 ->attach() call. Individual descriptions:
269 bind_request() connects a socket to a particular client driver.
270 It looks up the specified device ID in the list of registered
271 drivers, binds it to the socket, and tries to create an instance
272 of the device. unbind_request() deletes a driver instance.
274 Bind_device() associates a device driver with a particular socket.
275 It is normally called by Driver Services after it has identified
276 a newly inserted card. An instance of that driver will then be
277 eligible to register as a client of this socket.
279 Register_client() uses the dev_info_t handle to match the
280 caller with a socket. The driver must have already been bound
281 to a socket with bind_device() -- in fact, bind_device()
282 allocates the client structure that will be used.
284 ======================================================================*/
286 static int bind_request(struct pcmcia_socket *s, bind_info_t *bind_info)
288 struct pcmcia_driver *p_drv;
289 struct pcmcia_device *p_dev;
290 int ret = 0;
291 unsigned long flags;
293 s = pcmcia_get_socket(s);
294 if (!s)
295 return -EINVAL;
297 ds_dbg(2, "bind_request(%d, '%s')\n", s->sock,
298 (char *)bind_info->dev_info);
300 p_drv = get_pcmcia_driver(&bind_info->dev_info);
301 if (!p_drv) {
302 ret = -EINVAL;
303 goto err_put;
306 if (!try_module_get(p_drv->owner)) {
307 ret = -EINVAL;
308 goto err_put_driver;
311 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
312 list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
313 if (p_dev->func == bind_info->function) {
314 if ((p_dev->dev.driver == &p_drv->drv)) {
315 if (p_dev->cardmgr) {
316 /* if there's already a device
317 * registered, and it was registered
318 * by userspace before, we need to
319 * return the "instance". */
320 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
321 bind_info->instance = p_dev;
322 ret = -EBUSY;
323 goto err_put_module;
324 } else {
325 /* the correct driver managed to bind
326 * itself magically to the correct
327 * device. */
328 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
329 p_dev->cardmgr = p_drv;
330 ret = 0;
331 goto err_put_module;
333 } else if (!p_dev->dev.driver) {
334 /* there's already a device available where
335 * no device has been bound to yet. So we don't
336 * need to register a device! */
337 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
338 goto rescan;
342 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
344 p_dev = pcmcia_device_add(s, bind_info->function);
345 if (!p_dev) {
346 ret = -EIO;
347 goto err_put_module;
350 rescan:
351 p_dev->cardmgr = p_drv;
353 /* if a driver is already running, we can abort */
354 if (p_dev->dev.driver)
355 goto err_put_module;
358 * Prevent this racing with a card insertion.
360 mutex_lock(&s->skt_mutex);
361 ret = bus_rescan_devices(&pcmcia_bus_type);
362 mutex_unlock(&s->skt_mutex);
363 if (ret)
364 goto err_put_module;
366 /* check whether the driver indeed matched. I don't care if this
367 * is racy or not, because it can only happen on cardmgr access
368 * paths...
370 if (!(p_dev->dev.driver == &p_drv->drv))
371 p_dev->cardmgr = NULL;
373 err_put_module:
374 module_put(p_drv->owner);
375 err_put_driver:
376 put_driver(&p_drv->drv);
377 err_put:
378 pcmcia_put_socket(s);
380 return (ret);
381 } /* bind_request */
383 #ifdef CONFIG_CARDBUS
385 static struct pci_bus *pcmcia_lookup_bus(struct pcmcia_socket *s)
387 if (!s || !(s->state & SOCKET_CARDBUS))
388 return NULL;
390 return s->cb_dev->subordinate;
392 #endif
394 static int get_device_info(struct pcmcia_socket *s, bind_info_t *bind_info, int first)
396 dev_node_t *node;
397 struct pcmcia_device *p_dev;
398 struct pcmcia_driver *p_drv;
399 unsigned long flags;
400 int ret = 0;
402 #ifdef CONFIG_CARDBUS
404 * Some unbelievably ugly code to associate the PCI cardbus
405 * device and its driver with the PCMCIA "bind" information.
408 struct pci_bus *bus;
410 bus = pcmcia_lookup_bus(s);
411 if (bus) {
412 struct list_head *list;
413 struct pci_dev *dev = NULL;
415 list = bus->devices.next;
416 while (list != &bus->devices) {
417 struct pci_dev *pdev = pci_dev_b(list);
418 list = list->next;
420 if (first) {
421 dev = pdev;
422 break;
425 /* Try to handle "next" here some way? */
427 if (dev && dev->driver) {
428 strlcpy(bind_info->name, dev->driver->name, DEV_NAME_LEN);
429 bind_info->major = 0;
430 bind_info->minor = 0;
431 bind_info->next = NULL;
432 return 0;
436 #endif
438 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
439 list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
440 if (p_dev->func == bind_info->function) {
441 p_dev = pcmcia_get_dev(p_dev);
442 if (!p_dev)
443 continue;
444 goto found;
447 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
448 return -ENODEV;
450 found:
451 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
453 p_drv = to_pcmcia_drv(p_dev->dev.driver);
454 if (p_drv && !p_dev->_locked) {
455 ret = -EAGAIN;
456 goto err_put;
459 if (first)
460 node = p_dev->dev_node;
461 else
462 for (node = p_dev->dev_node; node; node = node->next)
463 if (node == bind_info->next)
464 break;
465 if (!node) {
466 ret = -ENODEV;
467 goto err_put;
470 strlcpy(bind_info->name, node->dev_name, DEV_NAME_LEN);
471 bind_info->major = node->major;
472 bind_info->minor = node->minor;
473 bind_info->next = node->next;
475 err_put:
476 pcmcia_put_dev(p_dev);
477 return (ret);
478 } /* get_device_info */
481 static int ds_open(struct inode *inode, struct file *file)
483 socket_t i = iminor(inode);
484 struct pcmcia_socket *s;
485 user_info_t *user;
486 static int warning_printed = 0;
488 ds_dbg(0, "ds_open(socket %d)\n", i);
490 s = pcmcia_get_socket_by_nr(i);
491 if (!s)
492 return -ENODEV;
493 s = pcmcia_get_socket(s);
494 if (!s)
495 return -ENODEV;
497 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
498 if (s->pcmcia_state.busy) {
499 pcmcia_put_socket(s);
500 return -EBUSY;
502 else
503 s->pcmcia_state.busy = 1;
506 user = kmalloc(sizeof(user_info_t), GFP_KERNEL);
507 if (!user) {
508 pcmcia_put_socket(s);
509 return -ENOMEM;
511 user->event_tail = user->event_head = 0;
512 user->next = s->user;
513 user->user_magic = USER_MAGIC;
514 user->socket = s;
515 s->user = user;
516 file->private_data = user;
518 if (!warning_printed) {
519 printk(KERN_INFO "pcmcia: Detected deprecated PCMCIA ioctl "
520 "usage from process: %s.\n", current->comm);
521 printk(KERN_INFO "pcmcia: This interface will soon be removed from "
522 "the kernel; please expect breakage unless you upgrade "
523 "to new tools.\n");
524 printk(KERN_INFO "pcmcia: see http://www.kernel.org/pub/linux/"
525 "utils/kernel/pcmcia/pcmcia.html for details.\n");
526 warning_printed = 1;
529 if (s->pcmcia_state.present)
530 queue_event(user, CS_EVENT_CARD_INSERTION);
531 return 0;
532 } /* ds_open */
534 /*====================================================================*/
536 static int ds_release(struct inode *inode, struct file *file)
538 struct pcmcia_socket *s;
539 user_info_t *user, **link;
541 ds_dbg(0, "ds_release(socket %d)\n", iminor(inode));
543 user = file->private_data;
544 if (CHECK_USER(user))
545 goto out;
547 s = user->socket;
549 /* Unlink user data structure */
550 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
551 s->pcmcia_state.busy = 0;
553 file->private_data = NULL;
554 for (link = &s->user; *link; link = &(*link)->next)
555 if (*link == user) break;
556 if (link == NULL)
557 goto out;
558 *link = user->next;
559 user->user_magic = 0;
560 kfree(user);
561 pcmcia_put_socket(s);
562 out:
563 return 0;
564 } /* ds_release */
566 /*====================================================================*/
568 static ssize_t ds_read(struct file *file, char __user *buf,
569 size_t count, loff_t *ppos)
571 struct pcmcia_socket *s;
572 user_info_t *user;
573 int ret;
575 ds_dbg(2, "ds_read(socket %d)\n", iminor(file->f_path.dentry->d_inode));
577 if (count < 4)
578 return -EINVAL;
580 user = file->private_data;
581 if (CHECK_USER(user))
582 return -EIO;
584 s = user->socket;
585 if (s->pcmcia_state.dead)
586 return -EIO;
588 ret = wait_event_interruptible(s->queue, !queue_empty(user));
589 if (ret == 0)
590 ret = put_user(get_queued_event(user), (int __user *)buf) ? -EFAULT : 4;
592 return ret;
593 } /* ds_read */
595 /*====================================================================*/
597 static ssize_t ds_write(struct file *file, const char __user *buf,
598 size_t count, loff_t *ppos)
600 ds_dbg(2, "ds_write(socket %d)\n", iminor(file->f_path.dentry->d_inode));
602 if (count != 4)
603 return -EINVAL;
604 if ((file->f_flags & O_ACCMODE) == O_RDONLY)
605 return -EBADF;
607 return -EIO;
608 } /* ds_write */
610 /*====================================================================*/
612 /* No kernel lock - fine */
613 static u_int ds_poll(struct file *file, poll_table *wait)
615 struct pcmcia_socket *s;
616 user_info_t *user;
618 ds_dbg(2, "ds_poll(socket %d)\n", iminor(file->f_path.dentry->d_inode));
620 user = file->private_data;
621 if (CHECK_USER(user))
622 return POLLERR;
623 s = user->socket;
625 * We don't check for a dead socket here since that
626 * will send cardmgr into an endless spin.
628 poll_wait(file, &s->queue, wait);
629 if (!queue_empty(user))
630 return POLLIN | POLLRDNORM;
631 return 0;
632 } /* ds_poll */
634 /*====================================================================*/
636 static int ds_ioctl(struct inode * inode, struct file * file,
637 u_int cmd, u_long arg)
639 struct pcmcia_socket *s;
640 void __user *uarg = (char __user *)arg;
641 u_int size;
642 int ret, err;
643 ds_ioctl_arg_t *buf;
644 user_info_t *user;
646 ds_dbg(2, "ds_ioctl(socket %d, %#x, %#lx)\n", iminor(inode), cmd, arg);
648 user = file->private_data;
649 if (CHECK_USER(user))
650 return -EIO;
652 s = user->socket;
653 if (s->pcmcia_state.dead)
654 return -EIO;
656 size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
657 if (size > sizeof(ds_ioctl_arg_t)) return -EINVAL;
659 /* Permission check */
660 if (!(cmd & IOC_OUT) && !capable(CAP_SYS_ADMIN))
661 return -EPERM;
663 if (cmd & IOC_IN) {
664 if (!access_ok(VERIFY_READ, uarg, size)) {
665 ds_dbg(3, "ds_ioctl(): verify_read = %d\n", -EFAULT);
666 return -EFAULT;
669 if (cmd & IOC_OUT) {
670 if (!access_ok(VERIFY_WRITE, uarg, size)) {
671 ds_dbg(3, "ds_ioctl(): verify_write = %d\n", -EFAULT);
672 return -EFAULT;
675 buf = kmalloc(sizeof(ds_ioctl_arg_t), GFP_KERNEL);
676 if (!buf)
677 return -ENOMEM;
679 err = ret = 0;
681 if (cmd & IOC_IN) {
682 if (__copy_from_user((char *)buf, uarg, size)) {
683 err = -EFAULT;
684 goto free_out;
688 switch (cmd) {
689 case DS_ADJUST_RESOURCE_INFO:
690 ret = pcmcia_adjust_resource_info(&buf->adjust);
691 break;
692 case DS_GET_CONFIGURATION_INFO:
693 if (buf->config.Function &&
694 (buf->config.Function >= s->functions))
695 ret = CS_BAD_ARGS;
696 else {
697 struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->config.Function);
698 ret = pccard_get_configuration_info(s, p_dev, &buf->config);
699 pcmcia_put_dev(p_dev);
701 break;
702 case DS_GET_FIRST_TUPLE:
703 mutex_lock(&s->skt_mutex);
704 pcmcia_validate_mem(s);
705 mutex_unlock(&s->skt_mutex);
706 ret = pccard_get_first_tuple(s, BIND_FN_ALL, &buf->tuple);
707 break;
708 case DS_GET_NEXT_TUPLE:
709 ret = pccard_get_next_tuple(s, BIND_FN_ALL, &buf->tuple);
710 break;
711 case DS_GET_TUPLE_DATA:
712 buf->tuple.TupleData = buf->tuple_parse.data;
713 buf->tuple.TupleDataMax = sizeof(buf->tuple_parse.data);
714 ret = pccard_get_tuple_data(s, &buf->tuple);
715 break;
716 case DS_PARSE_TUPLE:
717 buf->tuple.TupleData = buf->tuple_parse.data;
718 ret = pccard_parse_tuple(&buf->tuple, &buf->tuple_parse.parse);
719 break;
720 case DS_RESET_CARD:
721 ret = pccard_reset_card(s);
722 break;
723 case DS_GET_STATUS:
724 if (buf->status.Function &&
725 (buf->status.Function >= s->functions))
726 ret = CS_BAD_ARGS;
727 else {
728 struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->status.Function);
729 ret = pccard_get_status(s, p_dev, &buf->status);
730 pcmcia_put_dev(p_dev);
732 break;
733 case DS_VALIDATE_CIS:
734 mutex_lock(&s->skt_mutex);
735 pcmcia_validate_mem(s);
736 mutex_unlock(&s->skt_mutex);
737 ret = pccard_validate_cis(s, BIND_FN_ALL, &buf->cisinfo.Chains);
738 break;
739 case DS_SUSPEND_CARD:
740 ret = pcmcia_suspend_card(s);
741 break;
742 case DS_RESUME_CARD:
743 ret = pcmcia_resume_card(s);
744 break;
745 case DS_EJECT_CARD:
746 err = pcmcia_eject_card(s);
747 break;
748 case DS_INSERT_CARD:
749 err = pcmcia_insert_card(s);
750 break;
751 case DS_ACCESS_CONFIGURATION_REGISTER:
752 if ((buf->conf_reg.Action == CS_WRITE) && !capable(CAP_SYS_ADMIN)) {
753 err = -EPERM;
754 goto free_out;
757 ret = CS_BAD_ARGS;
759 if (!(buf->conf_reg.Function &&
760 (buf->conf_reg.Function >= s->functions))) {
761 struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->conf_reg.Function);
762 if (p_dev) {
763 ret = pcmcia_access_configuration_register(p_dev, &buf->conf_reg);
764 pcmcia_put_dev(p_dev);
767 break;
768 case DS_GET_FIRST_REGION:
769 case DS_GET_NEXT_REGION:
770 case DS_BIND_MTD:
771 if (!capable(CAP_SYS_ADMIN)) {
772 err = -EPERM;
773 goto free_out;
774 } else {
775 static int printed = 0;
776 if (!printed) {
777 printk(KERN_WARNING "2.6. kernels use pcmciamtd instead of memory_cs.c and do not require special\n");
778 printk(KERN_WARNING "MTD handling any more.\n");
779 printed++;
782 err = -EINVAL;
783 goto free_out;
784 break;
785 case DS_GET_FIRST_WINDOW:
786 ret = pcmcia_get_window(s, &buf->win_info.handle, 0,
787 &buf->win_info.window);
788 break;
789 case DS_GET_NEXT_WINDOW:
790 ret = pcmcia_get_window(s, &buf->win_info.handle,
791 buf->win_info.handle->index + 1, &buf->win_info.window);
792 break;
793 case DS_GET_MEM_PAGE:
794 ret = pcmcia_get_mem_page(buf->win_info.handle,
795 &buf->win_info.map);
796 break;
797 case DS_REPLACE_CIS:
798 ret = pcmcia_replace_cis(s, &buf->cisdump);
799 break;
800 case DS_BIND_REQUEST:
801 if (!capable(CAP_SYS_ADMIN)) {
802 err = -EPERM;
803 goto free_out;
805 err = bind_request(s, &buf->bind_info);
806 break;
807 case DS_GET_DEVICE_INFO:
808 err = get_device_info(s, &buf->bind_info, 1);
809 break;
810 case DS_GET_NEXT_DEVICE:
811 err = get_device_info(s, &buf->bind_info, 0);
812 break;
813 case DS_UNBIND_REQUEST:
814 err = 0;
815 break;
816 default:
817 err = -EINVAL;
820 if ((err == 0) && (ret != CS_SUCCESS)) {
821 ds_dbg(2, "ds_ioctl: ret = %d\n", ret);
822 switch (ret) {
823 case CS_BAD_SOCKET: case CS_NO_CARD:
824 err = -ENODEV; break;
825 case CS_BAD_ARGS: case CS_BAD_ATTRIBUTE: case CS_BAD_IRQ:
826 case CS_BAD_TUPLE:
827 err = -EINVAL; break;
828 case CS_IN_USE:
829 err = -EBUSY; break;
830 case CS_OUT_OF_RESOURCE:
831 err = -ENOSPC; break;
832 case CS_NO_MORE_ITEMS:
833 err = -ENODATA; break;
834 case CS_UNSUPPORTED_FUNCTION:
835 err = -ENOSYS; break;
836 default:
837 err = -EIO; break;
841 if (cmd & IOC_OUT) {
842 if (__copy_to_user(uarg, (char *)buf, size))
843 err = -EFAULT;
846 free_out:
847 kfree(buf);
848 return err;
849 } /* ds_ioctl */
851 /*====================================================================*/
853 static const struct file_operations ds_fops = {
854 .owner = THIS_MODULE,
855 .open = ds_open,
856 .release = ds_release,
857 .ioctl = ds_ioctl,
858 .read = ds_read,
859 .write = ds_write,
860 .poll = ds_poll,
863 void __init pcmcia_setup_ioctl(void) {
864 int i;
866 /* Set up character device for user mode clients */
867 i = register_chrdev(0, "pcmcia", &ds_fops);
868 if (i < 0)
869 printk(KERN_NOTICE "unable to find a free device # for "
870 "Driver Services (error=%d)\n", i);
871 else
872 major_dev = i;
874 #ifdef CONFIG_PROC_FS
875 proc_pccard = proc_mkdir("bus/pccard", NULL);
876 if (proc_pccard)
877 create_proc_read_entry("drivers",0,proc_pccard,proc_read_drivers,NULL);
878 #endif
882 void __exit pcmcia_cleanup_ioctl(void) {
883 #ifdef CONFIG_PROC_FS
884 if (proc_pccard) {
885 remove_proc_entry("drivers", proc_pccard);
886 remove_proc_entry("bus/pccard", NULL);
888 #endif
889 if (major_dev != -1)
890 unregister_chrdev(major_dev, "pcmcia");