OMAP3 SRF: Generic shared resource f/w
[linux-ginger.git] / drivers / pcmcia / pcmcia_ioctl.c
blob32c44040c1e8bd00734f51e3fd96aa5fcc10bb38
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/seq_file.h>
31 #include <linux/smp_lock.h>
32 #include <linux/workqueue.h>
34 #include <pcmcia/cs_types.h>
35 #include <pcmcia/cs.h>
36 #include <pcmcia/cistpl.h>
37 #include <pcmcia/cisreg.h>
38 #include <pcmcia/ds.h>
39 #include <pcmcia/ss.h>
41 #include "cs_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 CONFIG_PCMCIA_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 *_m)
111 struct seq_file *m = _m;
112 struct pcmcia_driver *p_drv = container_of(driver,
113 struct pcmcia_driver, drv);
115 seq_printf(m, "%-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 return 0;
125 static int pccard_drivers_proc_show(struct seq_file *m, void *v)
127 return bus_for_each_drv(&pcmcia_bus_type, NULL,
128 m, proc_read_drivers_callback);
131 static int pccard_drivers_proc_open(struct inode *inode, struct file *file)
133 return single_open(file, pccard_drivers_proc_show, NULL);
136 static const struct file_operations pccard_drivers_proc_fops = {
137 .owner = THIS_MODULE,
138 .open = pccard_drivers_proc_open,
139 .read = seq_read,
140 .llseek = seq_lseek,
141 .release = single_release,
143 #endif
146 #ifdef CONFIG_PCMCIA_PROBE
148 static int adjust_irq(struct pcmcia_socket *s, adjust_t *adj)
150 int irq;
151 u32 mask;
153 irq = adj->resource.irq.IRQ;
154 if ((irq < 0) || (irq > 15))
155 return -EINVAL;
157 if (adj->Action != REMOVE_MANAGED_RESOURCE)
158 return 0;
160 mask = 1 << irq;
162 if (!(s->irq_mask & mask))
163 return 0;
165 s->irq_mask &= ~mask;
167 return 0;
170 #else
172 static inline int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) {
173 return 0;
176 #endif
178 static int pcmcia_adjust_resource_info(adjust_t *adj)
180 struct pcmcia_socket *s;
181 int ret = -ENOSYS;
182 unsigned long flags;
184 down_read(&pcmcia_socket_list_rwsem);
185 list_for_each_entry(s, &pcmcia_socket_list, socket_list) {
187 if (adj->Resource == RES_IRQ)
188 ret = adjust_irq(s, adj);
190 else if (s->resource_ops->add_io) {
191 unsigned long begin, end;
193 /* you can't use the old interface if the new
194 * one was used before */
195 spin_lock_irqsave(&s->lock, flags);
196 if ((s->resource_setup_new) &&
197 !(s->resource_setup_old)) {
198 spin_unlock_irqrestore(&s->lock, flags);
199 continue;
200 } else if (!(s->resource_setup_old))
201 s->resource_setup_old = 1;
202 spin_unlock_irqrestore(&s->lock, flags);
204 switch (adj->Resource) {
205 case RES_MEMORY_RANGE:
206 begin = adj->resource.memory.Base;
207 end = adj->resource.memory.Base + adj->resource.memory.Size - 1;
208 if (s->resource_ops->add_mem)
209 ret =s->resource_ops->add_mem(s, adj->Action, begin, end);
210 case RES_IO_RANGE:
211 begin = adj->resource.io.BasePort;
212 end = adj->resource.io.BasePort + adj->resource.io.NumPorts - 1;
213 if (s->resource_ops->add_io)
214 ret = s->resource_ops->add_io(s, adj->Action, begin, end);
216 if (!ret) {
217 /* as there's no way we know this is the
218 * last call to adjust_resource_info, we
219 * always need to assume this is the latest
220 * one... */
221 spin_lock_irqsave(&s->lock, flags);
222 s->resource_setup_done = 1;
223 spin_unlock_irqrestore(&s->lock, flags);
227 up_read(&pcmcia_socket_list_rwsem);
229 return (ret);
232 /** pccard_get_status
234 * Get the current socket state bits. We don't support the latched
235 * SocketState yet: I haven't seen any point for it.
238 static int pccard_get_status(struct pcmcia_socket *s,
239 struct pcmcia_device *p_dev,
240 cs_status_t *status)
242 config_t *c;
243 int val;
245 s->ops->get_status(s, &val);
246 status->CardState = status->SocketState = 0;
247 status->CardState |= (val & SS_DETECT) ? CS_EVENT_CARD_DETECT : 0;
248 status->CardState |= (val & SS_CARDBUS) ? CS_EVENT_CB_DETECT : 0;
249 status->CardState |= (val & SS_3VCARD) ? CS_EVENT_3VCARD : 0;
250 status->CardState |= (val & SS_XVCARD) ? CS_EVENT_XVCARD : 0;
251 if (s->state & SOCKET_SUSPEND)
252 status->CardState |= CS_EVENT_PM_SUSPEND;
253 if (!(s->state & SOCKET_PRESENT))
254 return -ENODEV;
256 c = (p_dev) ? p_dev->function_config : NULL;
258 if ((c != NULL) && (c->state & CONFIG_LOCKED) &&
259 (c->IntType & (INT_MEMORY_AND_IO | INT_ZOOMED_VIDEO))) {
260 u_char reg;
261 if (c->CardValues & PRESENT_PIN_REPLACE) {
262 pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_PRR)>>1, 1, &reg);
263 status->CardState |=
264 (reg & PRR_WP_STATUS) ? CS_EVENT_WRITE_PROTECT : 0;
265 status->CardState |=
266 (reg & PRR_READY_STATUS) ? CS_EVENT_READY_CHANGE : 0;
267 status->CardState |=
268 (reg & PRR_BVD2_STATUS) ? CS_EVENT_BATTERY_LOW : 0;
269 status->CardState |=
270 (reg & PRR_BVD1_STATUS) ? CS_EVENT_BATTERY_DEAD : 0;
271 } else {
272 /* No PRR? Then assume we're always ready */
273 status->CardState |= CS_EVENT_READY_CHANGE;
275 if (c->CardValues & PRESENT_EXT_STATUS) {
276 pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_ESR)>>1, 1, &reg);
277 status->CardState |=
278 (reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0;
280 return 0;
282 status->CardState |=
283 (val & SS_WRPROT) ? CS_EVENT_WRITE_PROTECT : 0;
284 status->CardState |=
285 (val & SS_BATDEAD) ? CS_EVENT_BATTERY_DEAD : 0;
286 status->CardState |=
287 (val & SS_BATWARN) ? CS_EVENT_BATTERY_LOW : 0;
288 status->CardState |=
289 (val & SS_READY) ? CS_EVENT_READY_CHANGE : 0;
290 return 0;
291 } /* pccard_get_status */
293 static int pccard_get_configuration_info(struct pcmcia_socket *s,
294 struct pcmcia_device *p_dev,
295 config_info_t *config)
297 config_t *c;
299 if (!(s->state & SOCKET_PRESENT))
300 return -ENODEV;
303 #ifdef CONFIG_CARDBUS
304 if (s->state & SOCKET_CARDBUS) {
305 memset(config, 0, sizeof(config_info_t));
306 config->Vcc = s->socket.Vcc;
307 config->Vpp1 = config->Vpp2 = s->socket.Vpp;
308 config->Option = s->cb_dev->subordinate->number;
309 if (s->state & SOCKET_CARDBUS_CONFIG) {
310 config->Attributes = CONF_VALID_CLIENT;
311 config->IntType = INT_CARDBUS;
312 config->AssignedIRQ = s->irq.AssignedIRQ;
313 if (config->AssignedIRQ)
314 config->Attributes |= CONF_ENABLE_IRQ;
315 if (s->io[0].res) {
316 config->BasePort1 = s->io[0].res->start;
317 config->NumPorts1 = s->io[0].res->end -
318 config->BasePort1 + 1;
321 return 0;
323 #endif
325 if (p_dev) {
326 c = p_dev->function_config;
327 config->Function = p_dev->func;
328 } else {
329 c = NULL;
330 config->Function = 0;
333 if ((c == NULL) || !(c->state & CONFIG_LOCKED)) {
334 config->Attributes = 0;
335 config->Vcc = s->socket.Vcc;
336 config->Vpp1 = config->Vpp2 = s->socket.Vpp;
337 return 0;
340 config->Attributes = c->Attributes | CONF_VALID_CLIENT;
341 config->Vcc = s->socket.Vcc;
342 config->Vpp1 = config->Vpp2 = s->socket.Vpp;
343 config->IntType = c->IntType;
344 config->ConfigBase = c->ConfigBase;
345 config->Status = c->Status;
346 config->Pin = c->Pin;
347 config->Copy = c->Copy;
348 config->Option = c->Option;
349 config->ExtStatus = c->ExtStatus;
350 config->Present = config->CardValues = c->CardValues;
351 config->IRQAttributes = c->irq.Attributes;
352 config->AssignedIRQ = s->irq.AssignedIRQ;
353 config->BasePort1 = c->io.BasePort1;
354 config->NumPorts1 = c->io.NumPorts1;
355 config->Attributes1 = c->io.Attributes1;
356 config->BasePort2 = c->io.BasePort2;
357 config->NumPorts2 = c->io.NumPorts2;
358 config->Attributes2 = c->io.Attributes2;
359 config->IOAddrLines = c->io.IOAddrLines;
361 return 0;
362 } /* pccard_get_configuration_info */
365 /*======================================================================
367 These manage a ring buffer of events pending for one user process
369 ======================================================================*/
372 static int queue_empty(user_info_t *user)
374 return (user->event_head == user->event_tail);
377 static event_t get_queued_event(user_info_t *user)
379 user->event_tail = (user->event_tail+1) % MAX_EVENTS;
380 return user->event[user->event_tail];
383 static void queue_event(user_info_t *user, event_t event)
385 user->event_head = (user->event_head+1) % MAX_EVENTS;
386 if (user->event_head == user->event_tail)
387 user->event_tail = (user->event_tail+1) % MAX_EVENTS;
388 user->event[user->event_head] = event;
391 void handle_event(struct pcmcia_socket *s, event_t event)
393 user_info_t *user;
394 for (user = s->user; user; user = user->next)
395 queue_event(user, event);
396 wake_up_interruptible(&s->queue);
400 /*======================================================================
402 bind_request() and bind_device() are merged by now. Register_client()
403 is called right at the end of bind_request(), during the driver's
404 ->attach() call. Individual descriptions:
406 bind_request() connects a socket to a particular client driver.
407 It looks up the specified device ID in the list of registered
408 drivers, binds it to the socket, and tries to create an instance
409 of the device. unbind_request() deletes a driver instance.
411 Bind_device() associates a device driver with a particular socket.
412 It is normally called by Driver Services after it has identified
413 a newly inserted card. An instance of that driver will then be
414 eligible to register as a client of this socket.
416 Register_client() uses the dev_info_t handle to match the
417 caller with a socket. The driver must have already been bound
418 to a socket with bind_device() -- in fact, bind_device()
419 allocates the client structure that will be used.
421 ======================================================================*/
423 static int bind_request(struct pcmcia_socket *s, bind_info_t *bind_info)
425 struct pcmcia_driver *p_drv;
426 struct pcmcia_device *p_dev;
427 int ret = 0;
428 unsigned long flags;
430 s = pcmcia_get_socket(s);
431 if (!s)
432 return -EINVAL;
434 ds_dbg(2, "bind_request(%d, '%s')\n", s->sock,
435 (char *)bind_info->dev_info);
437 p_drv = get_pcmcia_driver(&bind_info->dev_info);
438 if (!p_drv) {
439 ret = -EINVAL;
440 goto err_put;
443 if (!try_module_get(p_drv->owner)) {
444 ret = -EINVAL;
445 goto err_put_driver;
448 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
449 list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
450 if (p_dev->func == bind_info->function) {
451 if ((p_dev->dev.driver == &p_drv->drv)) {
452 if (p_dev->cardmgr) {
453 /* if there's already a device
454 * registered, and it was registered
455 * by userspace before, we need to
456 * return the "instance". */
457 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
458 bind_info->instance = p_dev;
459 ret = -EBUSY;
460 goto err_put_module;
461 } else {
462 /* the correct driver managed to bind
463 * itself magically to the correct
464 * device. */
465 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
466 p_dev->cardmgr = p_drv;
467 ret = 0;
468 goto err_put_module;
470 } else if (!p_dev->dev.driver) {
471 /* there's already a device available where
472 * no device has been bound to yet. So we don't
473 * need to register a device! */
474 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
475 goto rescan;
479 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
481 p_dev = pcmcia_device_add(s, bind_info->function);
482 if (!p_dev) {
483 ret = -EIO;
484 goto err_put_module;
487 rescan:
488 p_dev->cardmgr = p_drv;
490 /* if a driver is already running, we can abort */
491 if (p_dev->dev.driver)
492 goto err_put_module;
495 * Prevent this racing with a card insertion.
497 mutex_lock(&s->skt_mutex);
498 ret = bus_rescan_devices(&pcmcia_bus_type);
499 mutex_unlock(&s->skt_mutex);
500 if (ret)
501 goto err_put_module;
503 /* check whether the driver indeed matched. I don't care if this
504 * is racy or not, because it can only happen on cardmgr access
505 * paths...
507 if (!(p_dev->dev.driver == &p_drv->drv))
508 p_dev->cardmgr = NULL;
510 err_put_module:
511 module_put(p_drv->owner);
512 err_put_driver:
513 put_driver(&p_drv->drv);
514 err_put:
515 pcmcia_put_socket(s);
517 return (ret);
518 } /* bind_request */
520 #ifdef CONFIG_CARDBUS
522 static struct pci_bus *pcmcia_lookup_bus(struct pcmcia_socket *s)
524 if (!s || !(s->state & SOCKET_CARDBUS))
525 return NULL;
527 return s->cb_dev->subordinate;
529 #endif
531 static int get_device_info(struct pcmcia_socket *s, bind_info_t *bind_info, int first)
533 dev_node_t *node;
534 struct pcmcia_device *p_dev;
535 struct pcmcia_driver *p_drv;
536 unsigned long flags;
537 int ret = 0;
539 #ifdef CONFIG_CARDBUS
541 * Some unbelievably ugly code to associate the PCI cardbus
542 * device and its driver with the PCMCIA "bind" information.
545 struct pci_bus *bus;
547 bus = pcmcia_lookup_bus(s);
548 if (bus) {
549 struct list_head *list;
550 struct pci_dev *dev = NULL;
552 list = bus->devices.next;
553 while (list != &bus->devices) {
554 struct pci_dev *pdev = pci_dev_b(list);
555 list = list->next;
557 if (first) {
558 dev = pdev;
559 break;
562 /* Try to handle "next" here some way? */
564 if (dev && dev->driver) {
565 strlcpy(bind_info->name, dev->driver->name, DEV_NAME_LEN);
566 bind_info->major = 0;
567 bind_info->minor = 0;
568 bind_info->next = NULL;
569 return 0;
573 #endif
575 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
576 list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
577 if (p_dev->func == bind_info->function) {
578 p_dev = pcmcia_get_dev(p_dev);
579 if (!p_dev)
580 continue;
581 goto found;
584 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
585 return -ENODEV;
587 found:
588 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
590 p_drv = to_pcmcia_drv(p_dev->dev.driver);
591 if (p_drv && !p_dev->_locked) {
592 ret = -EAGAIN;
593 goto err_put;
596 if (first)
597 node = p_dev->dev_node;
598 else
599 for (node = p_dev->dev_node; node; node = node->next)
600 if (node == bind_info->next)
601 break;
602 if (!node) {
603 ret = -ENODEV;
604 goto err_put;
607 strlcpy(bind_info->name, node->dev_name, DEV_NAME_LEN);
608 bind_info->major = node->major;
609 bind_info->minor = node->minor;
610 bind_info->next = node->next;
612 err_put:
613 pcmcia_put_dev(p_dev);
614 return (ret);
615 } /* get_device_info */
618 static int ds_open(struct inode *inode, struct file *file)
620 socket_t i = iminor(inode);
621 struct pcmcia_socket *s;
622 user_info_t *user;
623 static int warning_printed = 0;
624 int ret = 0;
626 ds_dbg(0, "ds_open(socket %d)\n", i);
628 lock_kernel();
629 s = pcmcia_get_socket_by_nr(i);
630 if (!s) {
631 ret = -ENODEV;
632 goto out;
634 s = pcmcia_get_socket(s);
635 if (!s) {
636 ret = -ENODEV;
637 goto out;
640 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
641 if (s->pcmcia_state.busy) {
642 pcmcia_put_socket(s);
643 ret = -EBUSY;
644 goto out;
646 else
647 s->pcmcia_state.busy = 1;
650 user = kmalloc(sizeof(user_info_t), GFP_KERNEL);
651 if (!user) {
652 pcmcia_put_socket(s);
653 ret = -ENOMEM;
654 goto out;
656 user->event_tail = user->event_head = 0;
657 user->next = s->user;
658 user->user_magic = USER_MAGIC;
659 user->socket = s;
660 s->user = user;
661 file->private_data = user;
663 if (!warning_printed) {
664 printk(KERN_INFO "pcmcia: Detected deprecated PCMCIA ioctl "
665 "usage from process: %s.\n", current->comm);
666 printk(KERN_INFO "pcmcia: This interface will soon be removed from "
667 "the kernel; please expect breakage unless you upgrade "
668 "to new tools.\n");
669 printk(KERN_INFO "pcmcia: see http://www.kernel.org/pub/linux/"
670 "utils/kernel/pcmcia/pcmcia.html for details.\n");
671 warning_printed = 1;
674 if (s->pcmcia_state.present)
675 queue_event(user, CS_EVENT_CARD_INSERTION);
676 out:
677 unlock_kernel();
678 return ret;
679 } /* ds_open */
681 /*====================================================================*/
683 static int ds_release(struct inode *inode, struct file *file)
685 struct pcmcia_socket *s;
686 user_info_t *user, **link;
688 ds_dbg(0, "ds_release(socket %d)\n", iminor(inode));
690 user = file->private_data;
691 if (CHECK_USER(user))
692 goto out;
694 s = user->socket;
696 /* Unlink user data structure */
697 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
698 s->pcmcia_state.busy = 0;
700 file->private_data = NULL;
701 for (link = &s->user; *link; link = &(*link)->next)
702 if (*link == user) break;
703 if (link == NULL)
704 goto out;
705 *link = user->next;
706 user->user_magic = 0;
707 kfree(user);
708 pcmcia_put_socket(s);
709 out:
710 return 0;
711 } /* ds_release */
713 /*====================================================================*/
715 static ssize_t ds_read(struct file *file, char __user *buf,
716 size_t count, loff_t *ppos)
718 struct pcmcia_socket *s;
719 user_info_t *user;
720 int ret;
722 ds_dbg(2, "ds_read(socket %d)\n", iminor(file->f_path.dentry->d_inode));
724 if (count < 4)
725 return -EINVAL;
727 user = file->private_data;
728 if (CHECK_USER(user))
729 return -EIO;
731 s = user->socket;
732 if (s->pcmcia_state.dead)
733 return -EIO;
735 ret = wait_event_interruptible(s->queue, !queue_empty(user));
736 if (ret == 0)
737 ret = put_user(get_queued_event(user), (int __user *)buf) ? -EFAULT : 4;
739 return ret;
740 } /* ds_read */
742 /*====================================================================*/
744 static ssize_t ds_write(struct file *file, const char __user *buf,
745 size_t count, loff_t *ppos)
747 ds_dbg(2, "ds_write(socket %d)\n", iminor(file->f_path.dentry->d_inode));
749 if (count != 4)
750 return -EINVAL;
751 if ((file->f_flags & O_ACCMODE) == O_RDONLY)
752 return -EBADF;
754 return -EIO;
755 } /* ds_write */
757 /*====================================================================*/
759 /* No kernel lock - fine */
760 static u_int ds_poll(struct file *file, poll_table *wait)
762 struct pcmcia_socket *s;
763 user_info_t *user;
765 ds_dbg(2, "ds_poll(socket %d)\n", iminor(file->f_path.dentry->d_inode));
767 user = file->private_data;
768 if (CHECK_USER(user))
769 return POLLERR;
770 s = user->socket;
772 * We don't check for a dead socket here since that
773 * will send cardmgr into an endless spin.
775 poll_wait(file, &s->queue, wait);
776 if (!queue_empty(user))
777 return POLLIN | POLLRDNORM;
778 return 0;
779 } /* ds_poll */
781 /*====================================================================*/
783 static int ds_ioctl(struct inode * inode, struct file * file,
784 u_int cmd, u_long arg)
786 struct pcmcia_socket *s;
787 void __user *uarg = (char __user *)arg;
788 u_int size;
789 int ret, err;
790 ds_ioctl_arg_t *buf;
791 user_info_t *user;
793 ds_dbg(2, "ds_ioctl(socket %d, %#x, %#lx)\n", iminor(inode), cmd, arg);
795 user = file->private_data;
796 if (CHECK_USER(user))
797 return -EIO;
799 s = user->socket;
800 if (s->pcmcia_state.dead)
801 return -EIO;
803 size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
804 if (size > sizeof(ds_ioctl_arg_t)) return -EINVAL;
806 /* Permission check */
807 if (!(cmd & IOC_OUT) && !capable(CAP_SYS_ADMIN))
808 return -EPERM;
810 if (cmd & IOC_IN) {
811 if (!access_ok(VERIFY_READ, uarg, size)) {
812 ds_dbg(3, "ds_ioctl(): verify_read = %d\n", -EFAULT);
813 return -EFAULT;
816 if (cmd & IOC_OUT) {
817 if (!access_ok(VERIFY_WRITE, uarg, size)) {
818 ds_dbg(3, "ds_ioctl(): verify_write = %d\n", -EFAULT);
819 return -EFAULT;
822 buf = kmalloc(sizeof(ds_ioctl_arg_t), GFP_KERNEL);
823 if (!buf)
824 return -ENOMEM;
826 err = ret = 0;
828 if (cmd & IOC_IN) {
829 if (__copy_from_user((char *)buf, uarg, size)) {
830 err = -EFAULT;
831 goto free_out;
835 switch (cmd) {
836 case DS_ADJUST_RESOURCE_INFO:
837 ret = pcmcia_adjust_resource_info(&buf->adjust);
838 break;
839 case DS_GET_CONFIGURATION_INFO:
840 if (buf->config.Function &&
841 (buf->config.Function >= s->functions))
842 ret = -EINVAL;
843 else {
844 struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->config.Function);
845 ret = pccard_get_configuration_info(s, p_dev, &buf->config);
846 pcmcia_put_dev(p_dev);
848 break;
849 case DS_GET_FIRST_TUPLE:
850 mutex_lock(&s->skt_mutex);
851 pcmcia_validate_mem(s);
852 mutex_unlock(&s->skt_mutex);
853 ret = pccard_get_first_tuple(s, BIND_FN_ALL, &buf->tuple);
854 break;
855 case DS_GET_NEXT_TUPLE:
856 ret = pccard_get_next_tuple(s, BIND_FN_ALL, &buf->tuple);
857 break;
858 case DS_GET_TUPLE_DATA:
859 buf->tuple.TupleData = buf->tuple_parse.data;
860 buf->tuple.TupleDataMax = sizeof(buf->tuple_parse.data);
861 ret = pccard_get_tuple_data(s, &buf->tuple);
862 break;
863 case DS_PARSE_TUPLE:
864 buf->tuple.TupleData = buf->tuple_parse.data;
865 ret = pcmcia_parse_tuple(&buf->tuple, &buf->tuple_parse.parse);
866 break;
867 case DS_RESET_CARD:
868 ret = pcmcia_reset_card(s);
869 break;
870 case DS_GET_STATUS:
871 if (buf->status.Function &&
872 (buf->status.Function >= s->functions))
873 ret = -EINVAL;
874 else {
875 struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->status.Function);
876 ret = pccard_get_status(s, p_dev, &buf->status);
877 pcmcia_put_dev(p_dev);
879 break;
880 case DS_VALIDATE_CIS:
881 mutex_lock(&s->skt_mutex);
882 pcmcia_validate_mem(s);
883 mutex_unlock(&s->skt_mutex);
884 ret = pccard_validate_cis(s, BIND_FN_ALL, &buf->cisinfo.Chains);
885 break;
886 case DS_SUSPEND_CARD:
887 ret = pcmcia_suspend_card(s);
888 break;
889 case DS_RESUME_CARD:
890 ret = pcmcia_resume_card(s);
891 break;
892 case DS_EJECT_CARD:
893 err = pcmcia_eject_card(s);
894 break;
895 case DS_INSERT_CARD:
896 err = pcmcia_insert_card(s);
897 break;
898 case DS_ACCESS_CONFIGURATION_REGISTER:
899 if ((buf->conf_reg.Action == CS_WRITE) && !capable(CAP_SYS_ADMIN)) {
900 err = -EPERM;
901 goto free_out;
904 ret = -EINVAL;
906 if (!(buf->conf_reg.Function &&
907 (buf->conf_reg.Function >= s->functions))) {
908 struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->conf_reg.Function);
909 if (p_dev) {
910 ret = pcmcia_access_configuration_register(p_dev, &buf->conf_reg);
911 pcmcia_put_dev(p_dev);
914 break;
915 case DS_GET_FIRST_REGION:
916 case DS_GET_NEXT_REGION:
917 case DS_BIND_MTD:
918 if (!capable(CAP_SYS_ADMIN)) {
919 err = -EPERM;
920 goto free_out;
921 } else {
922 printk_once(KERN_WARNING
923 "2.6. kernels use pcmciamtd instead of memory_cs.c and do not require special\n");
924 printk_once(KERN_WARNING "MTD handling any more.\n");
926 err = -EINVAL;
927 goto free_out;
928 break;
929 case DS_GET_FIRST_WINDOW:
930 ret = pcmcia_get_window(s, &buf->win_info.handle, 0,
931 &buf->win_info.window);
932 break;
933 case DS_GET_NEXT_WINDOW:
934 ret = pcmcia_get_window(s, &buf->win_info.handle,
935 buf->win_info.handle->index + 1, &buf->win_info.window);
936 break;
937 case DS_GET_MEM_PAGE:
938 ret = pcmcia_get_mem_page(buf->win_info.handle,
939 &buf->win_info.map);
940 break;
941 case DS_REPLACE_CIS:
942 ret = pcmcia_replace_cis(s, buf->cisdump.Data, buf->cisdump.Length);
943 break;
944 case DS_BIND_REQUEST:
945 if (!capable(CAP_SYS_ADMIN)) {
946 err = -EPERM;
947 goto free_out;
949 err = bind_request(s, &buf->bind_info);
950 break;
951 case DS_GET_DEVICE_INFO:
952 err = get_device_info(s, &buf->bind_info, 1);
953 break;
954 case DS_GET_NEXT_DEVICE:
955 err = get_device_info(s, &buf->bind_info, 0);
956 break;
957 case DS_UNBIND_REQUEST:
958 err = 0;
959 break;
960 default:
961 err = -EINVAL;
964 if ((err == 0) && (ret != 0)) {
965 ds_dbg(2, "ds_ioctl: ret = %d\n", ret);
966 switch (ret) {
967 case -ENODEV:
968 case -EINVAL:
969 case -EBUSY:
970 case -ENOSYS:
971 err = ret;
972 break;
973 case -ENOMEM:
974 err = -ENOSPC; break;
975 case -ENOSPC:
976 err = -ENODATA; break;
977 default:
978 err = -EIO; break;
982 if (cmd & IOC_OUT) {
983 if (__copy_to_user(uarg, (char *)buf, size))
984 err = -EFAULT;
987 free_out:
988 kfree(buf);
989 return err;
990 } /* ds_ioctl */
992 /*====================================================================*/
994 static const struct file_operations ds_fops = {
995 .owner = THIS_MODULE,
996 .open = ds_open,
997 .release = ds_release,
998 .ioctl = ds_ioctl,
999 .read = ds_read,
1000 .write = ds_write,
1001 .poll = ds_poll,
1004 void __init pcmcia_setup_ioctl(void) {
1005 int i;
1007 /* Set up character device for user mode clients */
1008 i = register_chrdev(0, "pcmcia", &ds_fops);
1009 if (i < 0)
1010 printk(KERN_NOTICE "unable to find a free device # for "
1011 "Driver Services (error=%d)\n", i);
1012 else
1013 major_dev = i;
1015 #ifdef CONFIG_PROC_FS
1016 proc_pccard = proc_mkdir("bus/pccard", NULL);
1017 if (proc_pccard)
1018 proc_create("drivers", 0, proc_pccard, &pccard_drivers_proc_fops);
1019 #endif
1023 void __exit pcmcia_cleanup_ioctl(void) {
1024 #ifdef CONFIG_PROC_FS
1025 if (proc_pccard) {
1026 remove_proc_entry("drivers", proc_pccard);
1027 remove_proc_entry("bus/pccard", NULL);
1029 #endif
1030 if (major_dev != -1)
1031 unregister_chrdev(major_dev, "pcmcia");