Linux 2.6.27.11
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / pcmcia / pcmcia_ioctl.c
blob419f97fc9a625befbd2805ec1b0693a4bb1af6b1
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/smp_lock.h>
31 #include <linux/workqueue.h>
33 #include <pcmcia/cs_types.h>
34 #include <pcmcia/cs.h>
35 #include <pcmcia/cistpl.h>
36 #include <pcmcia/cisreg.h>
37 #include <pcmcia/ds.h>
38 #include <pcmcia/ss.h>
40 #include "cs_internal.h"
41 #include "ds_internal.h"
43 static int major_dev = -1;
46 /* Device user information */
47 #define MAX_EVENTS 32
48 #define USER_MAGIC 0x7ea4
49 #define CHECK_USER(u) \
50 (((u) == NULL) || ((u)->user_magic != USER_MAGIC))
52 typedef struct user_info_t {
53 u_int user_magic;
54 int event_head, event_tail;
55 event_t event[MAX_EVENTS];
56 struct user_info_t *next;
57 struct pcmcia_socket *socket;
58 } user_info_t;
61 #ifdef DEBUG
62 extern int ds_pc_debug;
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
72 static struct pcmcia_device *get_pcmcia_device(struct pcmcia_socket *s,
73 unsigned int function)
75 struct pcmcia_device *p_dev = NULL;
76 unsigned long flags;
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);
85 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
86 return NULL;
89 /* backwards-compatible accessing of driver --- by name! */
91 static struct pcmcia_driver *get_pcmcia_driver(dev_info_t *dev_info)
93 struct device_driver *drv;
94 struct pcmcia_driver *p_drv;
96 drv = driver_find((char *) dev_info, &pcmcia_bus_type);
97 if (!drv)
98 return NULL;
100 p_drv = container_of(drv, struct pcmcia_driver, drv);
102 return (p_drv);
106 #ifdef CONFIG_PROC_FS
107 static struct proc_dir_entry *proc_pccard = NULL;
109 static int proc_read_drivers_callback(struct device_driver *driver, void *d)
111 char **p = d;
112 struct pcmcia_driver *p_drv = container_of(driver,
113 struct pcmcia_driver, drv);
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
120 #endif
122 d = (void *) p;
124 return 0;
127 static int proc_read_drivers(char *buf, char **start, off_t pos,
128 int count, int *eof, void *data)
130 char *p = buf;
131 int rc;
133 rc = bus_for_each_drv(&pcmcia_bus_type, NULL,
134 (void *) &p, proc_read_drivers_callback);
135 if (rc < 0)
136 return rc;
138 return (p - buf);
140 #endif
143 #ifdef CONFIG_PCMCIA_PROBE
145 static int adjust_irq(struct pcmcia_socket *s, adjust_t *adj)
147 int irq;
148 u32 mask;
150 irq = adj->resource.irq.IRQ;
151 if ((irq < 0) || (irq > 15))
152 return CS_BAD_IRQ;
154 if (adj->Action != REMOVE_MANAGED_RESOURCE)
155 return 0;
157 mask = 1 << irq;
159 if (!(s->irq_mask & mask))
160 return 0;
162 s->irq_mask &= ~mask;
164 return 0;
167 #else
169 static inline int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) {
170 return CS_SUCCESS;
173 #endif
175 static int pcmcia_adjust_resource_info(adjust_t *adj)
177 struct pcmcia_socket *s;
178 int ret = CS_UNSUPPORTED_FUNCTION;
179 unsigned long flags;
181 down_read(&pcmcia_socket_list_rwsem);
182 list_for_each_entry(s, &pcmcia_socket_list, socket_list) {
184 if (adj->Resource == RES_IRQ)
185 ret = adjust_irq(s, adj);
187 else if (s->resource_ops->add_io) {
188 unsigned long begin, end;
190 /* you can't use the old interface if the new
191 * one was used before */
192 spin_lock_irqsave(&s->lock, flags);
193 if ((s->resource_setup_new) &&
194 !(s->resource_setup_old)) {
195 spin_unlock_irqrestore(&s->lock, flags);
196 continue;
197 } else if (!(s->resource_setup_old))
198 s->resource_setup_old = 1;
199 spin_unlock_irqrestore(&s->lock, flags);
201 switch (adj->Resource) {
202 case RES_MEMORY_RANGE:
203 begin = adj->resource.memory.Base;
204 end = adj->resource.memory.Base + adj->resource.memory.Size - 1;
205 if (s->resource_ops->add_mem)
206 ret =s->resource_ops->add_mem(s, adj->Action, begin, end);
207 case RES_IO_RANGE:
208 begin = adj->resource.io.BasePort;
209 end = adj->resource.io.BasePort + adj->resource.io.NumPorts - 1;
210 if (s->resource_ops->add_io)
211 ret = s->resource_ops->add_io(s, adj->Action, begin, end);
213 if (!ret) {
214 /* as there's no way we know this is the
215 * last call to adjust_resource_info, we
216 * always need to assume this is the latest
217 * one... */
218 spin_lock_irqsave(&s->lock, flags);
219 s->resource_setup_done = 1;
220 spin_unlock_irqrestore(&s->lock, flags);
224 up_read(&pcmcia_socket_list_rwsem);
226 return (ret);
229 /** pccard_get_status
231 * Get the current socket state bits. We don't support the latched
232 * SocketState yet: I haven't seen any point for it.
235 static int pccard_get_status(struct pcmcia_socket *s,
236 struct pcmcia_device *p_dev,
237 cs_status_t *status)
239 config_t *c;
240 int val;
242 s->ops->get_status(s, &val);
243 status->CardState = status->SocketState = 0;
244 status->CardState |= (val & SS_DETECT) ? CS_EVENT_CARD_DETECT : 0;
245 status->CardState |= (val & SS_CARDBUS) ? CS_EVENT_CB_DETECT : 0;
246 status->CardState |= (val & SS_3VCARD) ? CS_EVENT_3VCARD : 0;
247 status->CardState |= (val & SS_XVCARD) ? CS_EVENT_XVCARD : 0;
248 if (s->state & SOCKET_SUSPEND)
249 status->CardState |= CS_EVENT_PM_SUSPEND;
250 if (!(s->state & SOCKET_PRESENT))
251 return CS_NO_CARD;
253 c = (p_dev) ? p_dev->function_config : NULL;
255 if ((c != NULL) && (c->state & CONFIG_LOCKED) &&
256 (c->IntType & (INT_MEMORY_AND_IO | INT_ZOOMED_VIDEO))) {
257 u_char reg;
258 if (c->CardValues & PRESENT_PIN_REPLACE) {
259 pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_PRR)>>1, 1, &reg);
260 status->CardState |=
261 (reg & PRR_WP_STATUS) ? CS_EVENT_WRITE_PROTECT : 0;
262 status->CardState |=
263 (reg & PRR_READY_STATUS) ? CS_EVENT_READY_CHANGE : 0;
264 status->CardState |=
265 (reg & PRR_BVD2_STATUS) ? CS_EVENT_BATTERY_LOW : 0;
266 status->CardState |=
267 (reg & PRR_BVD1_STATUS) ? CS_EVENT_BATTERY_DEAD : 0;
268 } else {
269 /* No PRR? Then assume we're always ready */
270 status->CardState |= CS_EVENT_READY_CHANGE;
272 if (c->CardValues & PRESENT_EXT_STATUS) {
273 pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_ESR)>>1, 1, &reg);
274 status->CardState |=
275 (reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0;
277 return CS_SUCCESS;
279 status->CardState |=
280 (val & SS_WRPROT) ? CS_EVENT_WRITE_PROTECT : 0;
281 status->CardState |=
282 (val & SS_BATDEAD) ? CS_EVENT_BATTERY_DEAD : 0;
283 status->CardState |=
284 (val & SS_BATWARN) ? CS_EVENT_BATTERY_LOW : 0;
285 status->CardState |=
286 (val & SS_READY) ? CS_EVENT_READY_CHANGE : 0;
287 return CS_SUCCESS;
288 } /* pccard_get_status */
290 /*======================================================================
292 These manage a ring buffer of events pending for one user process
294 ======================================================================*/
297 static int queue_empty(user_info_t *user)
299 return (user->event_head == user->event_tail);
302 static event_t get_queued_event(user_info_t *user)
304 user->event_tail = (user->event_tail+1) % MAX_EVENTS;
305 return user->event[user->event_tail];
308 static void queue_event(user_info_t *user, event_t event)
310 user->event_head = (user->event_head+1) % MAX_EVENTS;
311 if (user->event_head == user->event_tail)
312 user->event_tail = (user->event_tail+1) % MAX_EVENTS;
313 user->event[user->event_head] = event;
316 void handle_event(struct pcmcia_socket *s, event_t event)
318 user_info_t *user;
319 for (user = s->user; user; user = user->next)
320 queue_event(user, event);
321 wake_up_interruptible(&s->queue);
325 /*======================================================================
327 bind_request() and bind_device() are merged by now. Register_client()
328 is called right at the end of bind_request(), during the driver's
329 ->attach() call. Individual descriptions:
331 bind_request() connects a socket to a particular client driver.
332 It looks up the specified device ID in the list of registered
333 drivers, binds it to the socket, and tries to create an instance
334 of the device. unbind_request() deletes a driver instance.
336 Bind_device() associates a device driver with a particular socket.
337 It is normally called by Driver Services after it has identified
338 a newly inserted card. An instance of that driver will then be
339 eligible to register as a client of this socket.
341 Register_client() uses the dev_info_t handle to match the
342 caller with a socket. The driver must have already been bound
343 to a socket with bind_device() -- in fact, bind_device()
344 allocates the client structure that will be used.
346 ======================================================================*/
348 static int bind_request(struct pcmcia_socket *s, bind_info_t *bind_info)
350 struct pcmcia_driver *p_drv;
351 struct pcmcia_device *p_dev;
352 int ret = 0;
353 unsigned long flags;
355 s = pcmcia_get_socket(s);
356 if (!s)
357 return -EINVAL;
359 ds_dbg(2, "bind_request(%d, '%s')\n", s->sock,
360 (char *)bind_info->dev_info);
362 p_drv = get_pcmcia_driver(&bind_info->dev_info);
363 if (!p_drv) {
364 ret = -EINVAL;
365 goto err_put;
368 if (!try_module_get(p_drv->owner)) {
369 ret = -EINVAL;
370 goto err_put_driver;
373 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
374 list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
375 if (p_dev->func == bind_info->function) {
376 if ((p_dev->dev.driver == &p_drv->drv)) {
377 if (p_dev->cardmgr) {
378 /* if there's already a device
379 * registered, and it was registered
380 * by userspace before, we need to
381 * return the "instance". */
382 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
383 bind_info->instance = p_dev;
384 ret = -EBUSY;
385 goto err_put_module;
386 } else {
387 /* the correct driver managed to bind
388 * itself magically to the correct
389 * device. */
390 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
391 p_dev->cardmgr = p_drv;
392 ret = 0;
393 goto err_put_module;
395 } else if (!p_dev->dev.driver) {
396 /* there's already a device available where
397 * no device has been bound to yet. So we don't
398 * need to register a device! */
399 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
400 goto rescan;
404 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
406 p_dev = pcmcia_device_add(s, bind_info->function);
407 if (!p_dev) {
408 ret = -EIO;
409 goto err_put_module;
412 rescan:
413 p_dev->cardmgr = p_drv;
415 /* if a driver is already running, we can abort */
416 if (p_dev->dev.driver)
417 goto err_put_module;
420 * Prevent this racing with a card insertion.
422 mutex_lock(&s->skt_mutex);
423 ret = bus_rescan_devices(&pcmcia_bus_type);
424 mutex_unlock(&s->skt_mutex);
425 if (ret)
426 goto err_put_module;
428 /* check whether the driver indeed matched. I don't care if this
429 * is racy or not, because it can only happen on cardmgr access
430 * paths...
432 if (!(p_dev->dev.driver == &p_drv->drv))
433 p_dev->cardmgr = NULL;
435 err_put_module:
436 module_put(p_drv->owner);
437 err_put_driver:
438 put_driver(&p_drv->drv);
439 err_put:
440 pcmcia_put_socket(s);
442 return (ret);
443 } /* bind_request */
445 #ifdef CONFIG_CARDBUS
447 static struct pci_bus *pcmcia_lookup_bus(struct pcmcia_socket *s)
449 if (!s || !(s->state & SOCKET_CARDBUS))
450 return NULL;
452 return s->cb_dev->subordinate;
454 #endif
456 static int get_device_info(struct pcmcia_socket *s, bind_info_t *bind_info, int first)
458 dev_node_t *node;
459 struct pcmcia_device *p_dev;
460 struct pcmcia_driver *p_drv;
461 unsigned long flags;
462 int ret = 0;
464 #ifdef CONFIG_CARDBUS
466 * Some unbelievably ugly code to associate the PCI cardbus
467 * device and its driver with the PCMCIA "bind" information.
470 struct pci_bus *bus;
472 bus = pcmcia_lookup_bus(s);
473 if (bus) {
474 struct list_head *list;
475 struct pci_dev *dev = NULL;
477 list = bus->devices.next;
478 while (list != &bus->devices) {
479 struct pci_dev *pdev = pci_dev_b(list);
480 list = list->next;
482 if (first) {
483 dev = pdev;
484 break;
487 /* Try to handle "next" here some way? */
489 if (dev && dev->driver) {
490 strlcpy(bind_info->name, dev->driver->name, DEV_NAME_LEN);
491 bind_info->major = 0;
492 bind_info->minor = 0;
493 bind_info->next = NULL;
494 return 0;
498 #endif
500 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
501 list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
502 if (p_dev->func == bind_info->function) {
503 p_dev = pcmcia_get_dev(p_dev);
504 if (!p_dev)
505 continue;
506 goto found;
509 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
510 return -ENODEV;
512 found:
513 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
515 p_drv = to_pcmcia_drv(p_dev->dev.driver);
516 if (p_drv && !p_dev->_locked) {
517 ret = -EAGAIN;
518 goto err_put;
521 if (first)
522 node = p_dev->dev_node;
523 else
524 for (node = p_dev->dev_node; node; node = node->next)
525 if (node == bind_info->next)
526 break;
527 if (!node) {
528 ret = -ENODEV;
529 goto err_put;
532 strlcpy(bind_info->name, node->dev_name, DEV_NAME_LEN);
533 bind_info->major = node->major;
534 bind_info->minor = node->minor;
535 bind_info->next = node->next;
537 err_put:
538 pcmcia_put_dev(p_dev);
539 return (ret);
540 } /* get_device_info */
543 static int ds_open(struct inode *inode, struct file *file)
545 socket_t i = iminor(inode);
546 struct pcmcia_socket *s;
547 user_info_t *user;
548 static int warning_printed = 0;
549 int ret = 0;
551 ds_dbg(0, "ds_open(socket %d)\n", i);
553 lock_kernel();
554 s = pcmcia_get_socket_by_nr(i);
555 if (!s) {
556 ret = -ENODEV;
557 goto out;
559 s = pcmcia_get_socket(s);
560 if (!s) {
561 ret = -ENODEV;
562 goto out;
565 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
566 if (s->pcmcia_state.busy) {
567 pcmcia_put_socket(s);
568 ret = -EBUSY;
569 goto out;
571 else
572 s->pcmcia_state.busy = 1;
575 user = kmalloc(sizeof(user_info_t), GFP_KERNEL);
576 if (!user) {
577 pcmcia_put_socket(s);
578 ret = -ENOMEM;
579 goto out;
581 user->event_tail = user->event_head = 0;
582 user->next = s->user;
583 user->user_magic = USER_MAGIC;
584 user->socket = s;
585 s->user = user;
586 file->private_data = user;
588 if (!warning_printed) {
589 printk(KERN_INFO "pcmcia: Detected deprecated PCMCIA ioctl "
590 "usage from process: %s.\n", current->comm);
591 printk(KERN_INFO "pcmcia: This interface will soon be removed from "
592 "the kernel; please expect breakage unless you upgrade "
593 "to new tools.\n");
594 printk(KERN_INFO "pcmcia: see http://www.kernel.org/pub/linux/"
595 "utils/kernel/pcmcia/pcmcia.html for details.\n");
596 warning_printed = 1;
599 if (s->pcmcia_state.present)
600 queue_event(user, CS_EVENT_CARD_INSERTION);
601 out:
602 unlock_kernel();
603 return ret;
604 } /* ds_open */
606 /*====================================================================*/
608 static int ds_release(struct inode *inode, struct file *file)
610 struct pcmcia_socket *s;
611 user_info_t *user, **link;
613 ds_dbg(0, "ds_release(socket %d)\n", iminor(inode));
615 user = file->private_data;
616 if (CHECK_USER(user))
617 goto out;
619 s = user->socket;
621 /* Unlink user data structure */
622 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
623 s->pcmcia_state.busy = 0;
625 file->private_data = NULL;
626 for (link = &s->user; *link; link = &(*link)->next)
627 if (*link == user) break;
628 if (link == NULL)
629 goto out;
630 *link = user->next;
631 user->user_magic = 0;
632 kfree(user);
633 pcmcia_put_socket(s);
634 out:
635 return 0;
636 } /* ds_release */
638 /*====================================================================*/
640 static ssize_t ds_read(struct file *file, char __user *buf,
641 size_t count, loff_t *ppos)
643 struct pcmcia_socket *s;
644 user_info_t *user;
645 int ret;
647 ds_dbg(2, "ds_read(socket %d)\n", iminor(file->f_path.dentry->d_inode));
649 if (count < 4)
650 return -EINVAL;
652 user = file->private_data;
653 if (CHECK_USER(user))
654 return -EIO;
656 s = user->socket;
657 if (s->pcmcia_state.dead)
658 return -EIO;
660 ret = wait_event_interruptible(s->queue, !queue_empty(user));
661 if (ret == 0)
662 ret = put_user(get_queued_event(user), (int __user *)buf) ? -EFAULT : 4;
664 return ret;
665 } /* ds_read */
667 /*====================================================================*/
669 static ssize_t ds_write(struct file *file, const char __user *buf,
670 size_t count, loff_t *ppos)
672 ds_dbg(2, "ds_write(socket %d)\n", iminor(file->f_path.dentry->d_inode));
674 if (count != 4)
675 return -EINVAL;
676 if ((file->f_flags & O_ACCMODE) == O_RDONLY)
677 return -EBADF;
679 return -EIO;
680 } /* ds_write */
682 /*====================================================================*/
684 /* No kernel lock - fine */
685 static u_int ds_poll(struct file *file, poll_table *wait)
687 struct pcmcia_socket *s;
688 user_info_t *user;
690 ds_dbg(2, "ds_poll(socket %d)\n", iminor(file->f_path.dentry->d_inode));
692 user = file->private_data;
693 if (CHECK_USER(user))
694 return POLLERR;
695 s = user->socket;
697 * We don't check for a dead socket here since that
698 * will send cardmgr into an endless spin.
700 poll_wait(file, &s->queue, wait);
701 if (!queue_empty(user))
702 return POLLIN | POLLRDNORM;
703 return 0;
704 } /* ds_poll */
706 /*====================================================================*/
708 static int ds_ioctl(struct inode * inode, struct file * file,
709 u_int cmd, u_long arg)
711 struct pcmcia_socket *s;
712 void __user *uarg = (char __user *)arg;
713 u_int size;
714 int ret, err;
715 ds_ioctl_arg_t *buf;
716 user_info_t *user;
718 ds_dbg(2, "ds_ioctl(socket %d, %#x, %#lx)\n", iminor(inode), cmd, arg);
720 user = file->private_data;
721 if (CHECK_USER(user))
722 return -EIO;
724 s = user->socket;
725 if (s->pcmcia_state.dead)
726 return -EIO;
728 size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
729 if (size > sizeof(ds_ioctl_arg_t)) return -EINVAL;
731 /* Permission check */
732 if (!(cmd & IOC_OUT) && !capable(CAP_SYS_ADMIN))
733 return -EPERM;
735 if (cmd & IOC_IN) {
736 if (!access_ok(VERIFY_READ, uarg, size)) {
737 ds_dbg(3, "ds_ioctl(): verify_read = %d\n", -EFAULT);
738 return -EFAULT;
741 if (cmd & IOC_OUT) {
742 if (!access_ok(VERIFY_WRITE, uarg, size)) {
743 ds_dbg(3, "ds_ioctl(): verify_write = %d\n", -EFAULT);
744 return -EFAULT;
747 buf = kmalloc(sizeof(ds_ioctl_arg_t), GFP_KERNEL);
748 if (!buf)
749 return -ENOMEM;
751 err = ret = 0;
753 if (cmd & IOC_IN) {
754 if (__copy_from_user((char *)buf, uarg, size)) {
755 err = -EFAULT;
756 goto free_out;
760 switch (cmd) {
761 case DS_ADJUST_RESOURCE_INFO:
762 ret = pcmcia_adjust_resource_info(&buf->adjust);
763 break;
764 case DS_GET_CONFIGURATION_INFO:
765 if (buf->config.Function &&
766 (buf->config.Function >= s->functions))
767 ret = CS_BAD_ARGS;
768 else {
769 struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->config.Function);
770 ret = pccard_get_configuration_info(s, p_dev, &buf->config);
771 pcmcia_put_dev(p_dev);
773 break;
774 case DS_GET_FIRST_TUPLE:
775 mutex_lock(&s->skt_mutex);
776 pcmcia_validate_mem(s);
777 mutex_unlock(&s->skt_mutex);
778 ret = pccard_get_first_tuple(s, BIND_FN_ALL, &buf->tuple);
779 break;
780 case DS_GET_NEXT_TUPLE:
781 ret = pccard_get_next_tuple(s, BIND_FN_ALL, &buf->tuple);
782 break;
783 case DS_GET_TUPLE_DATA:
784 buf->tuple.TupleData = buf->tuple_parse.data;
785 buf->tuple.TupleDataMax = sizeof(buf->tuple_parse.data);
786 ret = pccard_get_tuple_data(s, &buf->tuple);
787 break;
788 case DS_PARSE_TUPLE:
789 buf->tuple.TupleData = buf->tuple_parse.data;
790 ret = pccard_parse_tuple(&buf->tuple, &buf->tuple_parse.parse);
791 break;
792 case DS_RESET_CARD:
793 ret = pccard_reset_card(s);
794 break;
795 case DS_GET_STATUS:
796 if (buf->status.Function &&
797 (buf->status.Function >= s->functions))
798 ret = CS_BAD_ARGS;
799 else {
800 struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->status.Function);
801 ret = pccard_get_status(s, p_dev, &buf->status);
802 pcmcia_put_dev(p_dev);
804 break;
805 case DS_VALIDATE_CIS:
806 mutex_lock(&s->skt_mutex);
807 pcmcia_validate_mem(s);
808 mutex_unlock(&s->skt_mutex);
809 ret = pccard_validate_cis(s, BIND_FN_ALL, &buf->cisinfo.Chains);
810 break;
811 case DS_SUSPEND_CARD:
812 ret = pcmcia_suspend_card(s);
813 break;
814 case DS_RESUME_CARD:
815 ret = pcmcia_resume_card(s);
816 break;
817 case DS_EJECT_CARD:
818 err = pcmcia_eject_card(s);
819 break;
820 case DS_INSERT_CARD:
821 err = pcmcia_insert_card(s);
822 break;
823 case DS_ACCESS_CONFIGURATION_REGISTER:
824 if ((buf->conf_reg.Action == CS_WRITE) && !capable(CAP_SYS_ADMIN)) {
825 err = -EPERM;
826 goto free_out;
829 ret = CS_BAD_ARGS;
831 if (!(buf->conf_reg.Function &&
832 (buf->conf_reg.Function >= s->functions))) {
833 struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->conf_reg.Function);
834 if (p_dev) {
835 ret = pcmcia_access_configuration_register(p_dev, &buf->conf_reg);
836 pcmcia_put_dev(p_dev);
839 break;
840 case DS_GET_FIRST_REGION:
841 case DS_GET_NEXT_REGION:
842 case DS_BIND_MTD:
843 if (!capable(CAP_SYS_ADMIN)) {
844 err = -EPERM;
845 goto free_out;
846 } else {
847 static int printed = 0;
848 if (!printed) {
849 printk(KERN_WARNING "2.6. kernels use pcmciamtd instead of memory_cs.c and do not require special\n");
850 printk(KERN_WARNING "MTD handling any more.\n");
851 printed++;
854 err = -EINVAL;
855 goto free_out;
856 break;
857 case DS_GET_FIRST_WINDOW:
858 ret = pcmcia_get_window(s, &buf->win_info.handle, 0,
859 &buf->win_info.window);
860 break;
861 case DS_GET_NEXT_WINDOW:
862 ret = pcmcia_get_window(s, &buf->win_info.handle,
863 buf->win_info.handle->index + 1, &buf->win_info.window);
864 break;
865 case DS_GET_MEM_PAGE:
866 ret = pcmcia_get_mem_page(buf->win_info.handle,
867 &buf->win_info.map);
868 break;
869 case DS_REPLACE_CIS:
870 ret = pcmcia_replace_cis(s, &buf->cisdump);
871 break;
872 case DS_BIND_REQUEST:
873 if (!capable(CAP_SYS_ADMIN)) {
874 err = -EPERM;
875 goto free_out;
877 err = bind_request(s, &buf->bind_info);
878 break;
879 case DS_GET_DEVICE_INFO:
880 err = get_device_info(s, &buf->bind_info, 1);
881 break;
882 case DS_GET_NEXT_DEVICE:
883 err = get_device_info(s, &buf->bind_info, 0);
884 break;
885 case DS_UNBIND_REQUEST:
886 err = 0;
887 break;
888 default:
889 err = -EINVAL;
892 if ((err == 0) && (ret != CS_SUCCESS)) {
893 ds_dbg(2, "ds_ioctl: ret = %d\n", ret);
894 switch (ret) {
895 case CS_BAD_SOCKET: case CS_NO_CARD:
896 err = -ENODEV; break;
897 case CS_BAD_ARGS: case CS_BAD_ATTRIBUTE: case CS_BAD_IRQ:
898 case CS_BAD_TUPLE:
899 err = -EINVAL; break;
900 case CS_IN_USE:
901 err = -EBUSY; break;
902 case CS_OUT_OF_RESOURCE:
903 err = -ENOSPC; break;
904 case CS_NO_MORE_ITEMS:
905 err = -ENODATA; break;
906 case CS_UNSUPPORTED_FUNCTION:
907 err = -ENOSYS; break;
908 default:
909 err = -EIO; break;
913 if (cmd & IOC_OUT) {
914 if (__copy_to_user(uarg, (char *)buf, size))
915 err = -EFAULT;
918 free_out:
919 kfree(buf);
920 return err;
921 } /* ds_ioctl */
923 /*====================================================================*/
925 static const struct file_operations ds_fops = {
926 .owner = THIS_MODULE,
927 .open = ds_open,
928 .release = ds_release,
929 .ioctl = ds_ioctl,
930 .read = ds_read,
931 .write = ds_write,
932 .poll = ds_poll,
935 void __init pcmcia_setup_ioctl(void) {
936 int i;
938 /* Set up character device for user mode clients */
939 i = register_chrdev(0, "pcmcia", &ds_fops);
940 if (i < 0)
941 printk(KERN_NOTICE "unable to find a free device # for "
942 "Driver Services (error=%d)\n", i);
943 else
944 major_dev = i;
946 #ifdef CONFIG_PROC_FS
947 proc_pccard = proc_mkdir("bus/pccard", NULL);
948 if (proc_pccard)
949 create_proc_read_entry("drivers",0,proc_pccard,proc_read_drivers,NULL);
950 #endif
954 void __exit pcmcia_cleanup_ioctl(void) {
955 #ifdef CONFIG_PROC_FS
956 if (proc_pccard) {
957 remove_proc_entry("drivers", proc_pccard);
958 remove_proc_entry("bus/pccard", NULL);
960 #endif
961 if (major_dev != -1)
962 unregister_chrdev(major_dev, "pcmcia");