added 2.6.29.6 aldebaran kernel
[nao-ulib.git] / kernel / 2.6.29.6-aldebaran-rt / drivers / pcmcia / pcmcia_ioctl.c
blob1703b20cad5d215ae1a2295329d87a2b253380f1
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"
42 static int major_dev = -1;
45 /* Device user information */
46 #define MAX_EVENTS 32
47 #define USER_MAGIC 0x7ea4
48 #define CHECK_USER(u) \
49 (((u) == NULL) || ((u)->user_magic != USER_MAGIC))
51 typedef struct user_info_t {
52 u_int user_magic;
53 int event_head, event_tail;
54 event_t event[MAX_EVENTS];
55 struct user_info_t *next;
56 struct pcmcia_socket *socket;
57 } user_info_t;
60 #ifdef CONFIG_PCMCIA_DEBUG
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); \
66 } while (0)
67 #else
68 #define ds_dbg(lvl, fmt, arg...) do { } while (0)
69 #endif
71 static struct pcmcia_device *get_pcmcia_device(struct pcmcia_socket *s,
72 unsigned int function)
74 struct pcmcia_device *p_dev = NULL;
75 unsigned long flags;
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);
85 return NULL;
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);
96 if (!drv)
97 return NULL;
99 p_drv = container_of(drv, struct pcmcia_driver, drv);
101 return (p_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)
110 char **p = 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
117 #else
119 #endif
121 d = (void *) p;
123 return 0;
126 static int proc_read_drivers(char *buf, char **start, off_t pos,
127 int count, int *eof, void *data)
129 char *p = buf;
130 int rc;
132 rc = bus_for_each_drv(&pcmcia_bus_type, NULL,
133 (void *) &p, proc_read_drivers_callback);
134 if (rc < 0)
135 return rc;
137 return (p - buf);
139 #endif
142 #ifdef CONFIG_PCMCIA_PROBE
144 static int adjust_irq(struct pcmcia_socket *s, adjust_t *adj)
146 int irq;
147 u32 mask;
149 irq = adj->resource.irq.IRQ;
150 if ((irq < 0) || (irq > 15))
151 return -EINVAL;
153 if (adj->Action != REMOVE_MANAGED_RESOURCE)
154 return 0;
156 mask = 1 << irq;
158 if (!(s->irq_mask & mask))
159 return 0;
161 s->irq_mask &= ~mask;
163 return 0;
166 #else
168 static inline int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) {
169 return 0;
172 #endif
174 static int pcmcia_adjust_resource_info(adjust_t *adj)
176 struct pcmcia_socket *s;
177 int ret = -ENOSYS;
178 unsigned long flags;
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);
195 continue;
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);
206 case RES_IO_RANGE:
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);
212 if (!ret) {
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
216 * one... */
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);
225 return (ret);
228 /** pccard_get_status
230 * Get the current socket state bits. We don't support the latched
231 * SocketState yet: I haven't seen any point for it.
234 static int pccard_get_status(struct pcmcia_socket *s,
235 struct pcmcia_device *p_dev,
236 cs_status_t *status)
238 config_t *c;
239 int val;
241 s->ops->get_status(s, &val);
242 status->CardState = status->SocketState = 0;
243 status->CardState |= (val & SS_DETECT) ? CS_EVENT_CARD_DETECT : 0;
244 status->CardState |= (val & SS_CARDBUS) ? CS_EVENT_CB_DETECT : 0;
245 status->CardState |= (val & SS_3VCARD) ? CS_EVENT_3VCARD : 0;
246 status->CardState |= (val & SS_XVCARD) ? CS_EVENT_XVCARD : 0;
247 if (s->state & SOCKET_SUSPEND)
248 status->CardState |= CS_EVENT_PM_SUSPEND;
249 if (!(s->state & SOCKET_PRESENT))
250 return -ENODEV;
252 c = (p_dev) ? p_dev->function_config : NULL;
254 if ((c != NULL) && (c->state & CONFIG_LOCKED) &&
255 (c->IntType & (INT_MEMORY_AND_IO | INT_ZOOMED_VIDEO))) {
256 u_char reg;
257 if (c->CardValues & PRESENT_PIN_REPLACE) {
258 pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_PRR)>>1, 1, &reg);
259 status->CardState |=
260 (reg & PRR_WP_STATUS) ? CS_EVENT_WRITE_PROTECT : 0;
261 status->CardState |=
262 (reg & PRR_READY_STATUS) ? CS_EVENT_READY_CHANGE : 0;
263 status->CardState |=
264 (reg & PRR_BVD2_STATUS) ? CS_EVENT_BATTERY_LOW : 0;
265 status->CardState |=
266 (reg & PRR_BVD1_STATUS) ? CS_EVENT_BATTERY_DEAD : 0;
267 } else {
268 /* No PRR? Then assume we're always ready */
269 status->CardState |= CS_EVENT_READY_CHANGE;
271 if (c->CardValues & PRESENT_EXT_STATUS) {
272 pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_ESR)>>1, 1, &reg);
273 status->CardState |=
274 (reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0;
276 return 0;
278 status->CardState |=
279 (val & SS_WRPROT) ? CS_EVENT_WRITE_PROTECT : 0;
280 status->CardState |=
281 (val & SS_BATDEAD) ? CS_EVENT_BATTERY_DEAD : 0;
282 status->CardState |=
283 (val & SS_BATWARN) ? CS_EVENT_BATTERY_LOW : 0;
284 status->CardState |=
285 (val & SS_READY) ? CS_EVENT_READY_CHANGE : 0;
286 return 0;
287 } /* pccard_get_status */
289 int pccard_get_configuration_info(struct pcmcia_socket *s,
290 struct pcmcia_device *p_dev,
291 config_info_t *config)
293 config_t *c;
295 if (!(s->state & SOCKET_PRESENT))
296 return -ENODEV;
299 #ifdef CONFIG_CARDBUS
300 if (s->state & SOCKET_CARDBUS) {
301 memset(config, 0, sizeof(config_info_t));
302 config->Vcc = s->socket.Vcc;
303 config->Vpp1 = config->Vpp2 = s->socket.Vpp;
304 config->Option = s->cb_dev->subordinate->number;
305 if (s->state & SOCKET_CARDBUS_CONFIG) {
306 config->Attributes = CONF_VALID_CLIENT;
307 config->IntType = INT_CARDBUS;
308 config->AssignedIRQ = s->irq.AssignedIRQ;
309 if (config->AssignedIRQ)
310 config->Attributes |= CONF_ENABLE_IRQ;
311 if (s->io[0].res) {
312 config->BasePort1 = s->io[0].res->start;
313 config->NumPorts1 = s->io[0].res->end -
314 config->BasePort1 + 1;
317 return 0;
319 #endif
321 if (p_dev) {
322 c = p_dev->function_config;
323 config->Function = p_dev->func;
324 } else {
325 c = NULL;
326 config->Function = 0;
329 if ((c == NULL) || !(c->state & CONFIG_LOCKED)) {
330 config->Attributes = 0;
331 config->Vcc = s->socket.Vcc;
332 config->Vpp1 = config->Vpp2 = s->socket.Vpp;
333 return 0;
336 config->Attributes = c->Attributes | CONF_VALID_CLIENT;
337 config->Vcc = s->socket.Vcc;
338 config->Vpp1 = config->Vpp2 = s->socket.Vpp;
339 config->IntType = c->IntType;
340 config->ConfigBase = c->ConfigBase;
341 config->Status = c->Status;
342 config->Pin = c->Pin;
343 config->Copy = c->Copy;
344 config->Option = c->Option;
345 config->ExtStatus = c->ExtStatus;
346 config->Present = config->CardValues = c->CardValues;
347 config->IRQAttributes = c->irq.Attributes;
348 config->AssignedIRQ = s->irq.AssignedIRQ;
349 config->BasePort1 = c->io.BasePort1;
350 config->NumPorts1 = c->io.NumPorts1;
351 config->Attributes1 = c->io.Attributes1;
352 config->BasePort2 = c->io.BasePort2;
353 config->NumPorts2 = c->io.NumPorts2;
354 config->Attributes2 = c->io.Attributes2;
355 config->IOAddrLines = c->io.IOAddrLines;
357 return 0;
358 } /* pccard_get_configuration_info */
361 /*======================================================================
363 These manage a ring buffer of events pending for one user process
365 ======================================================================*/
368 static int queue_empty(user_info_t *user)
370 return (user->event_head == user->event_tail);
373 static event_t get_queued_event(user_info_t *user)
375 user->event_tail = (user->event_tail+1) % MAX_EVENTS;
376 return user->event[user->event_tail];
379 static void queue_event(user_info_t *user, event_t event)
381 user->event_head = (user->event_head+1) % MAX_EVENTS;
382 if (user->event_head == user->event_tail)
383 user->event_tail = (user->event_tail+1) % MAX_EVENTS;
384 user->event[user->event_head] = event;
387 void handle_event(struct pcmcia_socket *s, event_t event)
389 user_info_t *user;
390 for (user = s->user; user; user = user->next)
391 queue_event(user, event);
392 wake_up_interruptible(&s->queue);
396 /*======================================================================
398 bind_request() and bind_device() are merged by now. Register_client()
399 is called right at the end of bind_request(), during the driver's
400 ->attach() call. Individual descriptions:
402 bind_request() connects a socket to a particular client driver.
403 It looks up the specified device ID in the list of registered
404 drivers, binds it to the socket, and tries to create an instance
405 of the device. unbind_request() deletes a driver instance.
407 Bind_device() associates a device driver with a particular socket.
408 It is normally called by Driver Services after it has identified
409 a newly inserted card. An instance of that driver will then be
410 eligible to register as a client of this socket.
412 Register_client() uses the dev_info_t handle to match the
413 caller with a socket. The driver must have already been bound
414 to a socket with bind_device() -- in fact, bind_device()
415 allocates the client structure that will be used.
417 ======================================================================*/
419 static int bind_request(struct pcmcia_socket *s, bind_info_t *bind_info)
421 struct pcmcia_driver *p_drv;
422 struct pcmcia_device *p_dev;
423 int ret = 0;
424 unsigned long flags;
426 s = pcmcia_get_socket(s);
427 if (!s)
428 return -EINVAL;
430 ds_dbg(2, "bind_request(%d, '%s')\n", s->sock,
431 (char *)bind_info->dev_info);
433 p_drv = get_pcmcia_driver(&bind_info->dev_info);
434 if (!p_drv) {
435 ret = -EINVAL;
436 goto err_put;
439 if (!try_module_get(p_drv->owner)) {
440 ret = -EINVAL;
441 goto err_put_driver;
444 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
445 list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
446 if (p_dev->func == bind_info->function) {
447 if ((p_dev->dev.driver == &p_drv->drv)) {
448 if (p_dev->cardmgr) {
449 /* if there's already a device
450 * registered, and it was registered
451 * by userspace before, we need to
452 * return the "instance". */
453 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
454 bind_info->instance = p_dev;
455 ret = -EBUSY;
456 goto err_put_module;
457 } else {
458 /* the correct driver managed to bind
459 * itself magically to the correct
460 * device. */
461 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
462 p_dev->cardmgr = p_drv;
463 ret = 0;
464 goto err_put_module;
466 } else if (!p_dev->dev.driver) {
467 /* there's already a device available where
468 * no device has been bound to yet. So we don't
469 * need to register a device! */
470 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
471 goto rescan;
475 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
477 p_dev = pcmcia_device_add(s, bind_info->function);
478 if (!p_dev) {
479 ret = -EIO;
480 goto err_put_module;
483 rescan:
484 p_dev->cardmgr = p_drv;
486 /* if a driver is already running, we can abort */
487 if (p_dev->dev.driver)
488 goto err_put_module;
491 * Prevent this racing with a card insertion.
493 mutex_lock(&s->skt_mutex);
494 ret = bus_rescan_devices(&pcmcia_bus_type);
495 mutex_unlock(&s->skt_mutex);
496 if (ret)
497 goto err_put_module;
499 /* check whether the driver indeed matched. I don't care if this
500 * is racy or not, because it can only happen on cardmgr access
501 * paths...
503 if (!(p_dev->dev.driver == &p_drv->drv))
504 p_dev->cardmgr = NULL;
506 err_put_module:
507 module_put(p_drv->owner);
508 err_put_driver:
509 put_driver(&p_drv->drv);
510 err_put:
511 pcmcia_put_socket(s);
513 return (ret);
514 } /* bind_request */
516 #ifdef CONFIG_CARDBUS
518 static struct pci_bus *pcmcia_lookup_bus(struct pcmcia_socket *s)
520 if (!s || !(s->state & SOCKET_CARDBUS))
521 return NULL;
523 return s->cb_dev->subordinate;
525 #endif
527 static int get_device_info(struct pcmcia_socket *s, bind_info_t *bind_info, int first)
529 dev_node_t *node;
530 struct pcmcia_device *p_dev;
531 struct pcmcia_driver *p_drv;
532 unsigned long flags;
533 int ret = 0;
535 #ifdef CONFIG_CARDBUS
537 * Some unbelievably ugly code to associate the PCI cardbus
538 * device and its driver with the PCMCIA "bind" information.
541 struct pci_bus *bus;
543 bus = pcmcia_lookup_bus(s);
544 if (bus) {
545 struct list_head *list;
546 struct pci_dev *dev = NULL;
548 list = bus->devices.next;
549 while (list != &bus->devices) {
550 struct pci_dev *pdev = pci_dev_b(list);
551 list = list->next;
553 if (first) {
554 dev = pdev;
555 break;
558 /* Try to handle "next" here some way? */
560 if (dev && dev->driver) {
561 strlcpy(bind_info->name, dev->driver->name, DEV_NAME_LEN);
562 bind_info->major = 0;
563 bind_info->minor = 0;
564 bind_info->next = NULL;
565 return 0;
569 #endif
571 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
572 list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
573 if (p_dev->func == bind_info->function) {
574 p_dev = pcmcia_get_dev(p_dev);
575 if (!p_dev)
576 continue;
577 goto found;
580 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
581 return -ENODEV;
583 found:
584 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
586 p_drv = to_pcmcia_drv(p_dev->dev.driver);
587 if (p_drv && !p_dev->_locked) {
588 ret = -EAGAIN;
589 goto err_put;
592 if (first)
593 node = p_dev->dev_node;
594 else
595 for (node = p_dev->dev_node; node; node = node->next)
596 if (node == bind_info->next)
597 break;
598 if (!node) {
599 ret = -ENODEV;
600 goto err_put;
603 strlcpy(bind_info->name, node->dev_name, DEV_NAME_LEN);
604 bind_info->major = node->major;
605 bind_info->minor = node->minor;
606 bind_info->next = node->next;
608 err_put:
609 pcmcia_put_dev(p_dev);
610 return (ret);
611 } /* get_device_info */
614 static int ds_open(struct inode *inode, struct file *file)
616 socket_t i = iminor(inode);
617 struct pcmcia_socket *s;
618 user_info_t *user;
619 static int warning_printed = 0;
620 int ret = 0;
622 ds_dbg(0, "ds_open(socket %d)\n", i);
624 lock_kernel();
625 s = pcmcia_get_socket_by_nr(i);
626 if (!s) {
627 ret = -ENODEV;
628 goto out;
630 s = pcmcia_get_socket(s);
631 if (!s) {
632 ret = -ENODEV;
633 goto out;
636 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
637 if (s->pcmcia_state.busy) {
638 pcmcia_put_socket(s);
639 ret = -EBUSY;
640 goto out;
642 else
643 s->pcmcia_state.busy = 1;
646 user = kmalloc(sizeof(user_info_t), GFP_KERNEL);
647 if (!user) {
648 pcmcia_put_socket(s);
649 ret = -ENOMEM;
650 goto out;
652 user->event_tail = user->event_head = 0;
653 user->next = s->user;
654 user->user_magic = USER_MAGIC;
655 user->socket = s;
656 s->user = user;
657 file->private_data = user;
659 if (!warning_printed) {
660 printk(KERN_INFO "pcmcia: Detected deprecated PCMCIA ioctl "
661 "usage from process: %s.\n", current->comm);
662 printk(KERN_INFO "pcmcia: This interface will soon be removed from "
663 "the kernel; please expect breakage unless you upgrade "
664 "to new tools.\n");
665 printk(KERN_INFO "pcmcia: see http://www.kernel.org/pub/linux/"
666 "utils/kernel/pcmcia/pcmcia.html for details.\n");
667 warning_printed = 1;
670 if (s->pcmcia_state.present)
671 queue_event(user, CS_EVENT_CARD_INSERTION);
672 out:
673 unlock_kernel();
674 return ret;
675 } /* ds_open */
677 /*====================================================================*/
679 static int ds_release(struct inode *inode, struct file *file)
681 struct pcmcia_socket *s;
682 user_info_t *user, **link;
684 ds_dbg(0, "ds_release(socket %d)\n", iminor(inode));
686 user = file->private_data;
687 if (CHECK_USER(user))
688 goto out;
690 s = user->socket;
692 /* Unlink user data structure */
693 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
694 s->pcmcia_state.busy = 0;
696 file->private_data = NULL;
697 for (link = &s->user; *link; link = &(*link)->next)
698 if (*link == user) break;
699 if (link == NULL)
700 goto out;
701 *link = user->next;
702 user->user_magic = 0;
703 kfree(user);
704 pcmcia_put_socket(s);
705 out:
706 return 0;
707 } /* ds_release */
709 /*====================================================================*/
711 static ssize_t ds_read(struct file *file, char __user *buf,
712 size_t count, loff_t *ppos)
714 struct pcmcia_socket *s;
715 user_info_t *user;
716 int ret;
718 ds_dbg(2, "ds_read(socket %d)\n", iminor(file->f_path.dentry->d_inode));
720 if (count < 4)
721 return -EINVAL;
723 user = file->private_data;
724 if (CHECK_USER(user))
725 return -EIO;
727 s = user->socket;
728 if (s->pcmcia_state.dead)
729 return -EIO;
731 ret = wait_event_interruptible(s->queue, !queue_empty(user));
732 if (ret == 0)
733 ret = put_user(get_queued_event(user), (int __user *)buf) ? -EFAULT : 4;
735 return ret;
736 } /* ds_read */
738 /*====================================================================*/
740 static ssize_t ds_write(struct file *file, const char __user *buf,
741 size_t count, loff_t *ppos)
743 ds_dbg(2, "ds_write(socket %d)\n", iminor(file->f_path.dentry->d_inode));
745 if (count != 4)
746 return -EINVAL;
747 if ((file->f_flags & O_ACCMODE) == O_RDONLY)
748 return -EBADF;
750 return -EIO;
751 } /* ds_write */
753 /*====================================================================*/
755 /* No kernel lock - fine */
756 static u_int ds_poll(struct file *file, poll_table *wait)
758 struct pcmcia_socket *s;
759 user_info_t *user;
761 ds_dbg(2, "ds_poll(socket %d)\n", iminor(file->f_path.dentry->d_inode));
763 user = file->private_data;
764 if (CHECK_USER(user))
765 return POLLERR;
766 s = user->socket;
768 * We don't check for a dead socket here since that
769 * will send cardmgr into an endless spin.
771 poll_wait(file, &s->queue, wait);
772 if (!queue_empty(user))
773 return POLLIN | POLLRDNORM;
774 return 0;
775 } /* ds_poll */
777 /*====================================================================*/
779 static int ds_ioctl(struct inode * inode, struct file * file,
780 u_int cmd, u_long arg)
782 struct pcmcia_socket *s;
783 void __user *uarg = (char __user *)arg;
784 u_int size;
785 int ret, err;
786 ds_ioctl_arg_t *buf;
787 user_info_t *user;
789 ds_dbg(2, "ds_ioctl(socket %d, %#x, %#lx)\n", iminor(inode), cmd, arg);
791 user = file->private_data;
792 if (CHECK_USER(user))
793 return -EIO;
795 s = user->socket;
796 if (s->pcmcia_state.dead)
797 return -EIO;
799 size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
800 if (size > sizeof(ds_ioctl_arg_t)) return -EINVAL;
802 /* Permission check */
803 if (!(cmd & IOC_OUT) && !capable(CAP_SYS_ADMIN))
804 return -EPERM;
806 if (cmd & IOC_IN) {
807 if (!access_ok(VERIFY_READ, uarg, size)) {
808 ds_dbg(3, "ds_ioctl(): verify_read = %d\n", -EFAULT);
809 return -EFAULT;
812 if (cmd & IOC_OUT) {
813 if (!access_ok(VERIFY_WRITE, uarg, size)) {
814 ds_dbg(3, "ds_ioctl(): verify_write = %d\n", -EFAULT);
815 return -EFAULT;
818 buf = kmalloc(sizeof(ds_ioctl_arg_t), GFP_KERNEL);
819 if (!buf)
820 return -ENOMEM;
822 err = ret = 0;
824 if (cmd & IOC_IN) {
825 if (__copy_from_user((char *)buf, uarg, size)) {
826 err = -EFAULT;
827 goto free_out;
831 switch (cmd) {
832 case DS_ADJUST_RESOURCE_INFO:
833 ret = pcmcia_adjust_resource_info(&buf->adjust);
834 break;
835 case DS_GET_CONFIGURATION_INFO:
836 if (buf->config.Function &&
837 (buf->config.Function >= s->functions))
838 ret = -EINVAL;
839 else {
840 struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->config.Function);
841 ret = pccard_get_configuration_info(s, p_dev, &buf->config);
842 pcmcia_put_dev(p_dev);
844 break;
845 case DS_GET_FIRST_TUPLE:
846 mutex_lock(&s->skt_mutex);
847 pcmcia_validate_mem(s);
848 mutex_unlock(&s->skt_mutex);
849 ret = pccard_get_first_tuple(s, BIND_FN_ALL, &buf->tuple);
850 break;
851 case DS_GET_NEXT_TUPLE:
852 ret = pccard_get_next_tuple(s, BIND_FN_ALL, &buf->tuple);
853 break;
854 case DS_GET_TUPLE_DATA:
855 buf->tuple.TupleData = buf->tuple_parse.data;
856 buf->tuple.TupleDataMax = sizeof(buf->tuple_parse.data);
857 ret = pccard_get_tuple_data(s, &buf->tuple);
858 break;
859 case DS_PARSE_TUPLE:
860 buf->tuple.TupleData = buf->tuple_parse.data;
861 ret = pcmcia_parse_tuple(&buf->tuple, &buf->tuple_parse.parse);
862 break;
863 case DS_RESET_CARD:
864 ret = pcmcia_reset_card(s);
865 break;
866 case DS_GET_STATUS:
867 if (buf->status.Function &&
868 (buf->status.Function >= s->functions))
869 ret = -EINVAL;
870 else {
871 struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->status.Function);
872 ret = pccard_get_status(s, p_dev, &buf->status);
873 pcmcia_put_dev(p_dev);
875 break;
876 case DS_VALIDATE_CIS:
877 mutex_lock(&s->skt_mutex);
878 pcmcia_validate_mem(s);
879 mutex_unlock(&s->skt_mutex);
880 ret = pccard_validate_cis(s, BIND_FN_ALL, &buf->cisinfo.Chains);
881 break;
882 case DS_SUSPEND_CARD:
883 ret = pcmcia_suspend_card(s);
884 break;
885 case DS_RESUME_CARD:
886 ret = pcmcia_resume_card(s);
887 break;
888 case DS_EJECT_CARD:
889 err = pcmcia_eject_card(s);
890 break;
891 case DS_INSERT_CARD:
892 err = pcmcia_insert_card(s);
893 break;
894 case DS_ACCESS_CONFIGURATION_REGISTER:
895 if ((buf->conf_reg.Action == CS_WRITE) && !capable(CAP_SYS_ADMIN)) {
896 err = -EPERM;
897 goto free_out;
900 ret = -EINVAL;
902 if (!(buf->conf_reg.Function &&
903 (buf->conf_reg.Function >= s->functions))) {
904 struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->conf_reg.Function);
905 if (p_dev) {
906 ret = pcmcia_access_configuration_register(p_dev, &buf->conf_reg);
907 pcmcia_put_dev(p_dev);
910 break;
911 case DS_GET_FIRST_REGION:
912 case DS_GET_NEXT_REGION:
913 case DS_BIND_MTD:
914 if (!capable(CAP_SYS_ADMIN)) {
915 err = -EPERM;
916 goto free_out;
917 } else {
918 static int printed = 0;
919 if (!printed) {
920 printk(KERN_WARNING "2.6. kernels use pcmciamtd instead of memory_cs.c and do not require special\n");
921 printk(KERN_WARNING "MTD handling any more.\n");
922 printed++;
925 err = -EINVAL;
926 goto free_out;
927 break;
928 case DS_GET_FIRST_WINDOW:
929 ret = pcmcia_get_window(s, &buf->win_info.handle, 0,
930 &buf->win_info.window);
931 break;
932 case DS_GET_NEXT_WINDOW:
933 ret = pcmcia_get_window(s, &buf->win_info.handle,
934 buf->win_info.handle->index + 1, &buf->win_info.window);
935 break;
936 case DS_GET_MEM_PAGE:
937 ret = pcmcia_get_mem_page(buf->win_info.handle,
938 &buf->win_info.map);
939 break;
940 case DS_REPLACE_CIS:
941 ret = pcmcia_replace_cis(s, buf->cisdump.Data, buf->cisdump.Length);
942 break;
943 case DS_BIND_REQUEST:
944 if (!capable(CAP_SYS_ADMIN)) {
945 err = -EPERM;
946 goto free_out;
948 err = bind_request(s, &buf->bind_info);
949 break;
950 case DS_GET_DEVICE_INFO:
951 err = get_device_info(s, &buf->bind_info, 1);
952 break;
953 case DS_GET_NEXT_DEVICE:
954 err = get_device_info(s, &buf->bind_info, 0);
955 break;
956 case DS_UNBIND_REQUEST:
957 err = 0;
958 break;
959 default:
960 err = -EINVAL;
963 if ((err == 0) && (ret != 0)) {
964 ds_dbg(2, "ds_ioctl: ret = %d\n", ret);
965 switch (ret) {
966 case -ENODEV:
967 case -EINVAL:
968 case -EBUSY:
969 case -ENOSYS:
970 err = ret;
971 break;
972 case -ENOMEM:
973 err = -ENOSPC; break;
974 case -ENOSPC:
975 err = -ENODATA; break;
976 default:
977 err = -EIO; break;
981 if (cmd & IOC_OUT) {
982 if (__copy_to_user(uarg, (char *)buf, size))
983 err = -EFAULT;
986 free_out:
987 kfree(buf);
988 return err;
989 } /* ds_ioctl */
991 /*====================================================================*/
993 static const struct file_operations ds_fops = {
994 .owner = THIS_MODULE,
995 .open = ds_open,
996 .release = ds_release,
997 .ioctl = ds_ioctl,
998 .read = ds_read,
999 .write = ds_write,
1000 .poll = ds_poll,
1003 void __init pcmcia_setup_ioctl(void) {
1004 int i;
1006 /* Set up character device for user mode clients */
1007 i = register_chrdev(0, "pcmcia", &ds_fops);
1008 if (i < 0)
1009 printk(KERN_NOTICE "unable to find a free device # for "
1010 "Driver Services (error=%d)\n", i);
1011 else
1012 major_dev = i;
1014 #ifdef CONFIG_PROC_FS
1015 proc_pccard = proc_mkdir("bus/pccard", NULL);
1016 if (proc_pccard)
1017 create_proc_read_entry("drivers",0,proc_pccard,proc_read_drivers,NULL);
1018 #endif
1022 void __exit pcmcia_cleanup_ioctl(void) {
1023 #ifdef CONFIG_PROC_FS
1024 if (proc_pccard) {
1025 remove_proc_entry("drivers", proc_pccard);
1026 remove_proc_entry("bus/pccard", NULL);
1028 #endif
1029 if (major_dev != -1)
1030 unregister_chrdev(major_dev, "pcmcia");