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 #define IN_CARD_SERVICES
33 #include <pcmcia/cs_types.h>
34 #include <pcmcia/cs.h>
35 #include <pcmcia/cistpl.h>
36 #include <pcmcia/ds.h>
37 #include <pcmcia/ss.h>
39 #include "cs_internal.h"
40 #include "ds_internal.h"
42 static int major_dev = -1;
45 /* Device user information */
47 #define USER_MAGIC 0x7ea4
48 #define CHECK_USER(u) \
49 (((u) == NULL) || ((u)->user_magic != USER_MAGIC))
51 typedef struct user_info_t {
53 int event_head, event_tail;
54 event_t event[MAX_EVENTS];
55 struct user_info_t *next;
56 struct pcmcia_socket *socket;
61 extern int ds_pc_debug;
63 #define ds_dbg(lvl, fmt, arg...) do { \
64 if (ds_pc_debug >= lvl) \
65 printk(KERN_DEBUG "ds: " fmt , ## arg); \
68 #define ds_dbg(lvl, fmt, arg...) do { } while (0)
71 static struct pcmcia_device *get_pcmcia_device(struct pcmcia_socket *s,
72 unsigned int function)
74 struct pcmcia_device *p_dev = NULL;
77 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
78 list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
79 if (p_dev->func == function) {
80 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
81 return pcmcia_get_dev(p_dev);
84 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
88 /* backwards-compatible accessing of driver --- by name! */
90 static struct pcmcia_driver *get_pcmcia_driver(dev_info_t *dev_info)
92 struct device_driver *drv;
93 struct pcmcia_driver *p_drv;
95 drv = driver_find((char *) dev_info, &pcmcia_bus_type);
99 p_drv = container_of(drv, struct pcmcia_driver, drv);
105 #ifdef CONFIG_PROC_FS
106 static struct proc_dir_entry *proc_pccard = NULL;
108 static int proc_read_drivers_callback(struct device_driver *driver, void *d)
111 struct pcmcia_driver *p_drv = container_of(driver,
112 struct pcmcia_driver, drv);
114 *p += sprintf(*p, "%-24.24s 1 %d\n", p_drv->drv.name,
115 #ifdef CONFIG_MODULE_UNLOAD
116 (p_drv->owner) ? module_refcount(p_drv->owner) : 1
126 static int proc_read_drivers(char *buf, char **start, off_t pos,
127 int count, int *eof, void *data)
132 rc = bus_for_each_drv(&pcmcia_bus_type, NULL,
133 (void *) &p, proc_read_drivers_callback);
142 #ifdef CONFIG_PCMCIA_PROBE
144 static int adjust_irq(struct pcmcia_socket *s, adjust_t *adj)
149 irq = adj->resource.irq.IRQ;
150 if ((irq < 0) || (irq > 15))
153 if (adj->Action != REMOVE_MANAGED_RESOURCE)
158 if (!(s->irq_mask & mask))
161 s->irq_mask &= ~mask;
168 static inline int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) {
174 static int pcmcia_adjust_resource_info(adjust_t *adj)
176 struct pcmcia_socket *s;
177 int ret = CS_UNSUPPORTED_FUNCTION;
180 down_read(&pcmcia_socket_list_rwsem);
181 list_for_each_entry(s, &pcmcia_socket_list, socket_list) {
183 if (adj->Resource == RES_IRQ)
184 ret = adjust_irq(s, adj);
186 else if (s->resource_ops->add_io) {
187 unsigned long begin, end;
189 /* you can't use the old interface if the new
190 * one was used before */
191 spin_lock_irqsave(&s->lock, flags);
192 if ((s->resource_setup_new) &&
193 !(s->resource_setup_old)) {
194 spin_unlock_irqrestore(&s->lock, flags);
196 } else if (!(s->resource_setup_old))
197 s->resource_setup_old = 1;
198 spin_unlock_irqrestore(&s->lock, flags);
200 switch (adj->Resource) {
201 case RES_MEMORY_RANGE:
202 begin = adj->resource.memory.Base;
203 end = adj->resource.memory.Base + adj->resource.memory.Size - 1;
204 if (s->resource_ops->add_mem)
205 ret =s->resource_ops->add_mem(s, adj->Action, begin, end);
207 begin = adj->resource.io.BasePort;
208 end = adj->resource.io.BasePort + adj->resource.io.NumPorts - 1;
209 if (s->resource_ops->add_io)
210 ret = s->resource_ops->add_io(s, adj->Action, begin, end);
213 /* as there's no way we know this is the
214 * last call to adjust_resource_info, we
215 * always need to assume this is the latest
217 spin_lock_irqsave(&s->lock, flags);
218 s->resource_setup_done = 1;
219 spin_unlock_irqrestore(&s->lock, flags);
223 up_read(&pcmcia_socket_list_rwsem);
229 /*======================================================================
231 These manage a ring buffer of events pending for one user process
233 ======================================================================*/
236 static int queue_empty(user_info_t *user)
238 return (user->event_head == user->event_tail);
241 static event_t get_queued_event(user_info_t *user)
243 user->event_tail = (user->event_tail+1) % MAX_EVENTS;
244 return user->event[user->event_tail];
247 static void queue_event(user_info_t *user, event_t event)
249 user->event_head = (user->event_head+1) % MAX_EVENTS;
250 if (user->event_head == user->event_tail)
251 user->event_tail = (user->event_tail+1) % MAX_EVENTS;
252 user->event[user->event_head] = event;
255 void handle_event(struct pcmcia_socket *s, event_t event)
258 for (user = s->user; user; user = user->next)
259 queue_event(user, event);
260 wake_up_interruptible(&s->queue);
264 /*======================================================================
266 bind_request() and bind_device() are merged by now. Register_client()
267 is called right at the end of bind_request(), during the driver's
268 ->attach() call. Individual descriptions:
270 bind_request() connects a socket to a particular client driver.
271 It looks up the specified device ID in the list of registered
272 drivers, binds it to the socket, and tries to create an instance
273 of the device. unbind_request() deletes a driver instance.
275 Bind_device() associates a device driver with a particular socket.
276 It is normally called by Driver Services after it has identified
277 a newly inserted card. An instance of that driver will then be
278 eligible to register as a client of this socket.
280 Register_client() uses the dev_info_t handle to match the
281 caller with a socket. The driver must have already been bound
282 to a socket with bind_device() -- in fact, bind_device()
283 allocates the client structure that will be used.
285 ======================================================================*/
287 static int bind_request(struct pcmcia_socket *s, bind_info_t *bind_info)
289 struct pcmcia_driver *p_drv;
290 struct pcmcia_device *p_dev;
294 s = pcmcia_get_socket(s);
298 ds_dbg(2, "bind_request(%d, '%s')\n", s->sock,
299 (char *)bind_info->dev_info);
301 p_drv = get_pcmcia_driver(&bind_info->dev_info);
307 if (!try_module_get(p_drv->owner)) {
312 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
313 list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
314 if (p_dev->func == bind_info->function) {
315 if ((p_dev->dev.driver == &p_drv->drv)) {
316 if (p_dev->cardmgr) {
317 /* if there's already a device
318 * registered, and it was registered
319 * by userspace before, we need to
320 * return the "instance". */
321 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
322 bind_info->instance = p_dev;
326 /* the correct driver managed to bind
327 * itself magically to the correct
329 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
330 p_dev->cardmgr = p_drv;
334 } else if (!p_dev->dev.driver) {
335 /* there's already a device available where
336 * no device has been bound to yet. So we don't
337 * need to register a device! */
338 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
343 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
345 p_dev = pcmcia_device_add(s, bind_info->function);
352 p_dev->cardmgr = p_drv;
354 /* if a driver is already running, we can abort */
355 if (p_dev->dev.driver)
359 * Prevent this racing with a card insertion.
361 mutex_lock(&s->skt_mutex);
362 ret = bus_rescan_devices(&pcmcia_bus_type);
363 mutex_unlock(&s->skt_mutex);
367 /* check whether the driver indeed matched. I don't care if this
368 * is racy or not, because it can only happen on cardmgr access
371 if (!(p_dev->dev.driver == &p_drv->drv))
372 p_dev->cardmgr = NULL;
375 module_put(p_drv->owner);
377 put_driver(&p_drv->drv);
379 pcmcia_put_socket(s);
384 #ifdef CONFIG_CARDBUS
386 static struct pci_bus *pcmcia_lookup_bus(struct pcmcia_socket *s)
388 if (!s || !(s->state & SOCKET_CARDBUS))
391 return s->cb_dev->subordinate;
395 static int get_device_info(struct pcmcia_socket *s, bind_info_t *bind_info, int first)
398 struct pcmcia_device *p_dev;
399 struct pcmcia_driver *p_drv;
403 #ifdef CONFIG_CARDBUS
405 * Some unbelievably ugly code to associate the PCI cardbus
406 * device and its driver with the PCMCIA "bind" information.
411 bus = pcmcia_lookup_bus(s);
413 struct list_head *list;
414 struct pci_dev *dev = NULL;
416 list = bus->devices.next;
417 while (list != &bus->devices) {
418 struct pci_dev *pdev = pci_dev_b(list);
426 /* Try to handle "next" here some way? */
428 if (dev && dev->driver) {
429 strlcpy(bind_info->name, dev->driver->name, DEV_NAME_LEN);
430 bind_info->major = 0;
431 bind_info->minor = 0;
432 bind_info->next = NULL;
439 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
440 list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
441 if (p_dev->func == bind_info->function) {
442 p_dev = pcmcia_get_dev(p_dev);
448 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
452 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
454 p_drv = to_pcmcia_drv(p_dev->dev.driver);
455 if (p_drv && !p_dev->_locked) {
461 node = p_dev->dev_node;
463 for (node = p_dev->dev_node; node; node = node->next)
464 if (node == bind_info->next)
471 strlcpy(bind_info->name, node->dev_name, DEV_NAME_LEN);
472 bind_info->major = node->major;
473 bind_info->minor = node->minor;
474 bind_info->next = node->next;
477 pcmcia_put_dev(p_dev);
479 } /* get_device_info */
482 static int ds_open(struct inode *inode, struct file *file)
484 socket_t i = iminor(inode);
485 struct pcmcia_socket *s;
487 static int warning_printed = 0;
489 ds_dbg(0, "ds_open(socket %d)\n", i);
491 s = pcmcia_get_socket_by_nr(i);
494 s = pcmcia_get_socket(s);
498 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
499 if (s->pcmcia_state.busy) {
500 pcmcia_put_socket(s);
504 s->pcmcia_state.busy = 1;
507 user = kmalloc(sizeof(user_info_t), GFP_KERNEL);
509 pcmcia_put_socket(s);
512 user->event_tail = user->event_head = 0;
513 user->next = s->user;
514 user->user_magic = USER_MAGIC;
517 file->private_data = user;
519 if (!warning_printed) {
520 printk(KERN_INFO "pcmcia: Detected deprecated PCMCIA ioctl "
521 "usage from process: %s.\n", current->comm);
522 printk(KERN_INFO "pcmcia: This interface will soon be removed from "
523 "the kernel; please expect breakage unless you upgrade "
525 printk(KERN_INFO "pcmcia: see http://www.kernel.org/pub/linux/"
526 "utils/kernel/pcmcia/pcmcia.html for details.\n");
530 if (s->pcmcia_state.present)
531 queue_event(user, CS_EVENT_CARD_INSERTION);
535 /*====================================================================*/
537 static int ds_release(struct inode *inode, struct file *file)
539 struct pcmcia_socket *s;
540 user_info_t *user, **link;
542 ds_dbg(0, "ds_release(socket %d)\n", iminor(inode));
544 user = file->private_data;
545 if (CHECK_USER(user))
550 /* Unlink user data structure */
551 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
552 s->pcmcia_state.busy = 0;
554 file->private_data = NULL;
555 for (link = &s->user; *link; link = &(*link)->next)
556 if (*link == user) break;
560 user->user_magic = 0;
562 pcmcia_put_socket(s);
567 /*====================================================================*/
569 static ssize_t ds_read(struct file *file, char __user *buf,
570 size_t count, loff_t *ppos)
572 struct pcmcia_socket *s;
576 ds_dbg(2, "ds_read(socket %d)\n", iminor(file->f_path.dentry->d_inode));
581 user = file->private_data;
582 if (CHECK_USER(user))
586 if (s->pcmcia_state.dead)
589 ret = wait_event_interruptible(s->queue, !queue_empty(user));
591 ret = put_user(get_queued_event(user), (int __user *)buf) ? -EFAULT : 4;
596 /*====================================================================*/
598 static ssize_t ds_write(struct file *file, const char __user *buf,
599 size_t count, loff_t *ppos)
601 ds_dbg(2, "ds_write(socket %d)\n", iminor(file->f_path.dentry->d_inode));
605 if ((file->f_flags & O_ACCMODE) == O_RDONLY)
611 /*====================================================================*/
613 /* No kernel lock - fine */
614 static u_int ds_poll(struct file *file, poll_table *wait)
616 struct pcmcia_socket *s;
619 ds_dbg(2, "ds_poll(socket %d)\n", iminor(file->f_path.dentry->d_inode));
621 user = file->private_data;
622 if (CHECK_USER(user))
626 * We don't check for a dead socket here since that
627 * will send cardmgr into an endless spin.
629 poll_wait(file, &s->queue, wait);
630 if (!queue_empty(user))
631 return POLLIN | POLLRDNORM;
635 /*====================================================================*/
637 static int ds_ioctl(struct inode * inode, struct file * file,
638 u_int cmd, u_long arg)
640 struct pcmcia_socket *s;
641 void __user *uarg = (char __user *)arg;
647 ds_dbg(2, "ds_ioctl(socket %d, %#x, %#lx)\n", iminor(inode), cmd, arg);
649 user = file->private_data;
650 if (CHECK_USER(user))
654 if (s->pcmcia_state.dead)
657 size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
658 if (size > sizeof(ds_ioctl_arg_t)) return -EINVAL;
660 /* Permission check */
661 if (!(cmd & IOC_OUT) && !capable(CAP_SYS_ADMIN))
665 if (!access_ok(VERIFY_READ, uarg, size)) {
666 ds_dbg(3, "ds_ioctl(): verify_read = %d\n", -EFAULT);
671 if (!access_ok(VERIFY_WRITE, uarg, size)) {
672 ds_dbg(3, "ds_ioctl(): verify_write = %d\n", -EFAULT);
676 buf = kmalloc(sizeof(ds_ioctl_arg_t), GFP_KERNEL);
683 if (__copy_from_user((char *)buf, uarg, size)) {
690 case DS_ADJUST_RESOURCE_INFO:
691 ret = pcmcia_adjust_resource_info(&buf->adjust);
693 case DS_GET_CONFIGURATION_INFO:
694 if (buf->config.Function &&
695 (buf->config.Function >= s->functions))
698 struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->config.Function);
699 ret = pccard_get_configuration_info(s, p_dev, &buf->config);
700 pcmcia_put_dev(p_dev);
703 case DS_GET_FIRST_TUPLE:
704 mutex_lock(&s->skt_mutex);
705 pcmcia_validate_mem(s);
706 mutex_unlock(&s->skt_mutex);
707 ret = pccard_get_first_tuple(s, BIND_FN_ALL, &buf->tuple);
709 case DS_GET_NEXT_TUPLE:
710 ret = pccard_get_next_tuple(s, BIND_FN_ALL, &buf->tuple);
712 case DS_GET_TUPLE_DATA:
713 buf->tuple.TupleData = buf->tuple_parse.data;
714 buf->tuple.TupleDataMax = sizeof(buf->tuple_parse.data);
715 ret = pccard_get_tuple_data(s, &buf->tuple);
718 buf->tuple.TupleData = buf->tuple_parse.data;
719 ret = pccard_parse_tuple(&buf->tuple, &buf->tuple_parse.parse);
722 ret = pccard_reset_card(s);
725 if (buf->status.Function &&
726 (buf->status.Function >= s->functions))
729 struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->status.Function);
730 ret = pccard_get_status(s, p_dev, &buf->status);
731 pcmcia_put_dev(p_dev);
734 case DS_VALIDATE_CIS:
735 mutex_lock(&s->skt_mutex);
736 pcmcia_validate_mem(s);
737 mutex_unlock(&s->skt_mutex);
738 ret = pccard_validate_cis(s, BIND_FN_ALL, &buf->cisinfo.Chains);
740 case DS_SUSPEND_CARD:
741 ret = pcmcia_suspend_card(s);
744 ret = pcmcia_resume_card(s);
747 err = pcmcia_eject_card(s);
750 err = pcmcia_insert_card(s);
752 case DS_ACCESS_CONFIGURATION_REGISTER:
753 if ((buf->conf_reg.Action == CS_WRITE) && !capable(CAP_SYS_ADMIN)) {
760 if (!(buf->conf_reg.Function &&
761 (buf->conf_reg.Function >= s->functions))) {
762 struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->conf_reg.Function);
764 ret = pcmcia_access_configuration_register(p_dev, &buf->conf_reg);
765 pcmcia_put_dev(p_dev);
769 case DS_GET_FIRST_REGION:
770 case DS_GET_NEXT_REGION:
772 if (!capable(CAP_SYS_ADMIN)) {
776 static int printed = 0;
778 printk(KERN_WARNING "2.6. kernels use pcmciamtd instead of memory_cs.c and do not require special\n");
779 printk(KERN_WARNING "MTD handling any more.\n");
786 case DS_GET_FIRST_WINDOW:
787 ret = pcmcia_get_window(s, &buf->win_info.handle, 0,
788 &buf->win_info.window);
790 case DS_GET_NEXT_WINDOW:
791 ret = pcmcia_get_window(s, &buf->win_info.handle,
792 buf->win_info.handle->index + 1, &buf->win_info.window);
794 case DS_GET_MEM_PAGE:
795 ret = pcmcia_get_mem_page(buf->win_info.handle,
799 ret = pcmcia_replace_cis(s, &buf->cisdump);
801 case DS_BIND_REQUEST:
802 if (!capable(CAP_SYS_ADMIN)) {
806 err = bind_request(s, &buf->bind_info);
808 case DS_GET_DEVICE_INFO:
809 err = get_device_info(s, &buf->bind_info, 1);
811 case DS_GET_NEXT_DEVICE:
812 err = get_device_info(s, &buf->bind_info, 0);
814 case DS_UNBIND_REQUEST:
821 if ((err == 0) && (ret != CS_SUCCESS)) {
822 ds_dbg(2, "ds_ioctl: ret = %d\n", ret);
824 case CS_BAD_SOCKET: case CS_NO_CARD:
825 err = -ENODEV; break;
826 case CS_BAD_ARGS: case CS_BAD_ATTRIBUTE: case CS_BAD_IRQ:
828 err = -EINVAL; break;
831 case CS_OUT_OF_RESOURCE:
832 err = -ENOSPC; break;
833 case CS_NO_MORE_ITEMS:
834 err = -ENODATA; break;
835 case CS_UNSUPPORTED_FUNCTION:
836 err = -ENOSYS; break;
843 if (__copy_to_user(uarg, (char *)buf, size))
852 /*====================================================================*/
854 static const struct file_operations ds_fops = {
855 .owner = THIS_MODULE,
857 .release = ds_release,
864 void __init pcmcia_setup_ioctl(void) {
867 /* Set up character device for user mode clients */
868 i = register_chrdev(0, "pcmcia", &ds_fops);
870 printk(KERN_NOTICE "unable to find a free device # for "
871 "Driver Services (error=%d)\n", i);
875 #ifdef CONFIG_PROC_FS
876 proc_pccard = proc_mkdir("bus/pccard", NULL);
878 create_proc_read_entry("drivers",0,proc_pccard,proc_read_drivers,NULL);
883 void __exit pcmcia_cleanup_ioctl(void) {
884 #ifdef CONFIG_PROC_FS
886 remove_proc_entry("drivers", proc_pccard);
887 remove_proc_entry("bus/pccard", NULL);
891 unregister_chrdev(major_dev, "pcmcia");