[PATCH] PCMCIA: handle sysfs, PCI errors
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / pcmcia / pcmcia_ioctl.c
CommitLineData
e7a480d2
DB
1/*
2 * pcmcia_ioctl.c -- ioctl interface for cardmgr and cardctl
3 *
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.
7 *
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.
11 *
12 * (C) 1999 David A. Hinds
13 * (C) 2003 - 2004 Dominik Brodowski
14 */
15
16/*
17 * This file will go away soon.
18 */
19
20
3b659fb8 21#include <linux/kernel.h>
e7a480d2 22#include <linux/module.h>
e7a480d2 23#include <linux/init.h>
e7a480d2 24#include <linux/major.h>
e7a480d2 25#include <linux/errno.h>
e7a480d2
DB
26#include <linux/ioctl.h>
27#include <linux/proc_fs.h>
28#include <linux/poll.h>
29#include <linux/pci.h>
e7a480d2 30#include <linux/workqueue.h>
e7a480d2
DB
31
32#define IN_CARD_SERVICES
e7a480d2
DB
33#include <pcmcia/cs_types.h>
34#include <pcmcia/cs.h>
e7a480d2
DB
35#include <pcmcia/cistpl.h>
36#include <pcmcia/ds.h>
37#include <pcmcia/ss.h>
38
39#include "cs_internal.h"
40#include "ds_internal.h"
41
42static int major_dev = -1;
43
44
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))
50
51typedef 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;
dc109497 56 struct pcmcia_socket *socket;
e7a480d2
DB
57} user_info_t;
58
59
60#ifdef DEBUG
61extern int ds_pc_debug;
62#define cs_socket_name(skt) ((skt)->dev.class_id)
63
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
71
855cdf13
DB
72static struct pcmcia_device *get_pcmcia_device(struct pcmcia_socket *s,
73 unsigned int function)
74{
75 struct pcmcia_device *p_dev = NULL;
76 unsigned long flags;
77
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);
83 }
84 }
85 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
86 return NULL;
87}
e7a480d2 88
e7a480d2
DB
89/* backwards-compatible accessing of driver --- by name! */
90
855cdf13 91static struct pcmcia_driver *get_pcmcia_driver(dev_info_t *dev_info)
e7a480d2
DB
92{
93 struct device_driver *drv;
94 struct pcmcia_driver *p_drv;
95
96 drv = driver_find((char *) dev_info, &pcmcia_bus_type);
97 if (!drv)
98 return NULL;
99
100 p_drv = container_of(drv, struct pcmcia_driver, drv);
101
102 return (p_drv);
103}
104
105
106#ifdef CONFIG_PROC_FS
107static struct proc_dir_entry *proc_pccard = NULL;
108
109static int proc_read_drivers_callback(struct device_driver *driver, void *d)
110{
111 char **p = d;
112 struct pcmcia_driver *p_drv = container_of(driver,
113 struct pcmcia_driver, drv);
114
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
119 1
120#endif
121 );
122 d = (void *) p;
123
124 return 0;
125}
126
127static int proc_read_drivers(char *buf, char **start, off_t pos,
128 int count, int *eof, void *data)
129{
130 char *p = buf;
4deb7c1e 131 int rc;
e7a480d2 132
4deb7c1e
JG
133 rc = bus_for_each_drv(&pcmcia_bus_type, NULL,
134 (void *) &p, proc_read_drivers_callback);
135 if (rc < 0)
136 return rc;
e7a480d2
DB
137
138 return (p - buf);
139}
140#endif
141
142/*======================================================================
143
144 These manage a ring buffer of events pending for one user process
145
146======================================================================*/
147
148
149static int queue_empty(user_info_t *user)
150{
151 return (user->event_head == user->event_tail);
152}
153
154static event_t get_queued_event(user_info_t *user)
155{
156 user->event_tail = (user->event_tail+1) % MAX_EVENTS;
157 return user->event[user->event_tail];
158}
159
160static void queue_event(user_info_t *user, event_t event)
161{
162 user->event_head = (user->event_head+1) % MAX_EVENTS;
163 if (user->event_head == user->event_tail)
164 user->event_tail = (user->event_tail+1) % MAX_EVENTS;
165 user->event[user->event_head] = event;
166}
167
dc109497 168void handle_event(struct pcmcia_socket *s, event_t event)
e7a480d2
DB
169{
170 user_info_t *user;
171 for (user = s->user; user; user = user->next)
172 queue_event(user, event);
173 wake_up_interruptible(&s->queue);
174}
175
176
177/*======================================================================
178
179 bind_request() and bind_device() are merged by now. Register_client()
180 is called right at the end of bind_request(), during the driver's
181 ->attach() call. Individual descriptions:
182
183 bind_request() connects a socket to a particular client driver.
184 It looks up the specified device ID in the list of registered
185 drivers, binds it to the socket, and tries to create an instance
186 of the device. unbind_request() deletes a driver instance.
187
188 Bind_device() associates a device driver with a particular socket.
189 It is normally called by Driver Services after it has identified
190 a newly inserted card. An instance of that driver will then be
191 eligible to register as a client of this socket.
192
193 Register_client() uses the dev_info_t handle to match the
194 caller with a socket. The driver must have already been bound
195 to a socket with bind_device() -- in fact, bind_device()
196 allocates the client structure that will be used.
197
198======================================================================*/
199
dc109497 200static int bind_request(struct pcmcia_socket *s, bind_info_t *bind_info)
e7a480d2
DB
201{
202 struct pcmcia_driver *p_drv;
203 struct pcmcia_device *p_dev;
204 int ret = 0;
205 unsigned long flags;
206
dc109497 207 s = pcmcia_get_socket(s);
e7a480d2
DB
208 if (!s)
209 return -EINVAL;
210
dc109497 211 ds_dbg(2, "bind_request(%d, '%s')\n", s->sock,
e7a480d2
DB
212 (char *)bind_info->dev_info);
213
214 p_drv = get_pcmcia_driver(&bind_info->dev_info);
215 if (!p_drv) {
216 ret = -EINVAL;
217 goto err_put;
218 }
219
220 if (!try_module_get(p_drv->owner)) {
221 ret = -EINVAL;
222 goto err_put_driver;
223 }
224
225 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
226 list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
227 if (p_dev->func == bind_info->function) {
228 if ((p_dev->dev.driver == &p_drv->drv)) {
229 if (p_dev->cardmgr) {
230 /* if there's already a device
231 * registered, and it was registered
232 * by userspace before, we need to
233 * return the "instance". */
234 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
fd238232 235 bind_info->instance = p_dev;
e7a480d2
DB
236 ret = -EBUSY;
237 goto err_put_module;
238 } else {
239 /* the correct driver managed to bind
240 * itself magically to the correct
241 * device. */
242 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
243 p_dev->cardmgr = p_drv;
244 ret = 0;
245 goto err_put_module;
246 }
247 } else if (!p_dev->dev.driver) {
248 /* there's already a device available where
249 * no device has been bound to yet. So we don't
250 * need to register a device! */
251 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
252 goto rescan;
253 }
254 }
255 }
256 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
257
258 p_dev = pcmcia_device_add(s, bind_info->function);
259 if (!p_dev) {
260 ret = -EIO;
261 goto err_put_module;
262 }
263
264rescan:
265 p_dev->cardmgr = p_drv;
266
267 /* if a driver is already running, we can abort */
268 if (p_dev->dev.driver)
269 goto err_put_module;
270
271 /*
272 * Prevent this racing with a card insertion.
273 */
7fe908dd 274 mutex_lock(&s->skt_mutex);
4deb7c1e 275 ret = bus_rescan_devices(&pcmcia_bus_type);
7fe908dd 276 mutex_unlock(&s->skt_mutex);
4deb7c1e
JG
277 if (ret)
278 goto err_put_module;
e7a480d2
DB
279
280 /* check whether the driver indeed matched. I don't care if this
281 * is racy or not, because it can only happen on cardmgr access
282 * paths...
283 */
284 if (!(p_dev->dev.driver == &p_drv->drv))
285 p_dev->cardmgr = NULL;
286
287 err_put_module:
288 module_put(p_drv->owner);
289 err_put_driver:
290 put_driver(&p_drv->drv);
291 err_put:
dc109497 292 pcmcia_put_socket(s);
e7a480d2
DB
293
294 return (ret);
295} /* bind_request */
296
33519ddd
DB
297#ifdef CONFIG_CARDBUS
298
299static struct pci_bus *pcmcia_lookup_bus(struct pcmcia_socket *s)
300{
301 if (!s || !(s->state & SOCKET_CARDBUS))
302 return NULL;
e7a480d2 303
33519ddd
DB
304 return s->cb_dev->subordinate;
305}
306#endif
e7a480d2 307
dc109497 308static int get_device_info(struct pcmcia_socket *s, bind_info_t *bind_info, int first)
e7a480d2
DB
309{
310 dev_node_t *node;
311 struct pcmcia_device *p_dev;
e2d40963 312 struct pcmcia_driver *p_drv;
e7a480d2
DB
313 unsigned long flags;
314 int ret = 0;
315
316#ifdef CONFIG_CARDBUS
317 /*
318 * Some unbelievably ugly code to associate the PCI cardbus
319 * device and its driver with the PCMCIA "bind" information.
320 */
321 {
322 struct pci_bus *bus;
323
dc109497 324 bus = pcmcia_lookup_bus(s);
e7a480d2
DB
325 if (bus) {
326 struct list_head *list;
327 struct pci_dev *dev = NULL;
328
329 list = bus->devices.next;
330 while (list != &bus->devices) {
331 struct pci_dev *pdev = pci_dev_b(list);
332 list = list->next;
333
334 if (first) {
335 dev = pdev;
336 break;
337 }
338
339 /* Try to handle "next" here some way? */
340 }
341 if (dev && dev->driver) {
342 strlcpy(bind_info->name, dev->driver->name, DEV_NAME_LEN);
343 bind_info->major = 0;
344 bind_info->minor = 0;
345 bind_info->next = NULL;
346 return 0;
347 }
348 }
349 }
350#endif
351
352 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
353 list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
354 if (p_dev->func == bind_info->function) {
355 p_dev = pcmcia_get_dev(p_dev);
356 if (!p_dev)
357 continue;
358 goto found;
359 }
360 }
361 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
362 return -ENODEV;
363
364 found:
365 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
366
e2d40963
DB
367 p_drv = to_pcmcia_drv(p_dev->dev.driver);
368 if (p_drv && !p_dev->_locked) {
e7a480d2
DB
369 ret = -EAGAIN;
370 goto err_put;
371 }
372
373 if (first)
fd238232 374 node = p_dev->dev_node;
e7a480d2 375 else
fd238232 376 for (node = p_dev->dev_node; node; node = node->next)
e7a480d2
DB
377 if (node == bind_info->next)
378 break;
379 if (!node) {
380 ret = -ENODEV;
381 goto err_put;
382 }
383
384 strlcpy(bind_info->name, node->dev_name, DEV_NAME_LEN);
385 bind_info->major = node->major;
386 bind_info->minor = node->minor;
387 bind_info->next = node->next;
388
389 err_put:
390 pcmcia_put_dev(p_dev);
391 return (ret);
392} /* get_device_info */
393
394
395static int ds_open(struct inode *inode, struct file *file)
396{
397 socket_t i = iminor(inode);
dc109497 398 struct pcmcia_socket *s;
e7a480d2 399 user_info_t *user;
c352ec8a 400 static int warning_printed = 0;
e7a480d2
DB
401
402 ds_dbg(0, "ds_open(socket %d)\n", i);
403
dc109497 404 s = pcmcia_get_socket_by_nr(i);
e7a480d2
DB
405 if (!s)
406 return -ENODEV;
dc109497 407 s = pcmcia_get_socket(s);
e7a480d2
DB
408 if (!s)
409 return -ENODEV;
410
411 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
b5e43913 412 if (s->pcmcia_state.busy) {
dc109497 413 pcmcia_put_socket(s);
e7a480d2
DB
414 return -EBUSY;
415 }
416 else
b5e43913 417 s->pcmcia_state.busy = 1;
e7a480d2
DB
418 }
419
420 user = kmalloc(sizeof(user_info_t), GFP_KERNEL);
421 if (!user) {
dc109497 422 pcmcia_put_socket(s);
e7a480d2
DB
423 return -ENOMEM;
424 }
425 user->event_tail = user->event_head = 0;
426 user->next = s->user;
427 user->user_magic = USER_MAGIC;
428 user->socket = s;
429 s->user = user;
430 file->private_data = user;
431
c352ec8a
DB
432 if (!warning_printed) {
433 printk(KERN_INFO "pcmcia: Detected deprecated PCMCIA ioctl "
73d58588 434 "usage from process: %s.\n", current->comm);
c352ec8a
DB
435 printk(KERN_INFO "pcmcia: This interface will soon be removed from "
436 "the kernel; please expect breakage unless you upgrade "
437 "to new tools.\n");
438 printk(KERN_INFO "pcmcia: see http://www.kernel.org/pub/linux/"
439 "utils/kernel/pcmcia/pcmcia.html for details.\n");
440 warning_printed = 1;
441 }
442
b5e43913 443 if (s->pcmcia_state.present)
e7a480d2
DB
444 queue_event(user, CS_EVENT_CARD_INSERTION);
445 return 0;
446} /* ds_open */
447
448/*====================================================================*/
449
450static int ds_release(struct inode *inode, struct file *file)
451{
dc109497 452 struct pcmcia_socket *s;
e7a480d2
DB
453 user_info_t *user, **link;
454
455 ds_dbg(0, "ds_release(socket %d)\n", iminor(inode));
456
457 user = file->private_data;
458 if (CHECK_USER(user))
459 goto out;
460
461 s = user->socket;
462
463 /* Unlink user data structure */
464 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
b5e43913 465 s->pcmcia_state.busy = 0;
e7a480d2
DB
466 }
467 file->private_data = NULL;
468 for (link = &s->user; *link; link = &(*link)->next)
469 if (*link == user) break;
470 if (link == NULL)
471 goto out;
472 *link = user->next;
473 user->user_magic = 0;
474 kfree(user);
dc109497 475 pcmcia_put_socket(s);
e7a480d2
DB
476out:
477 return 0;
478} /* ds_release */
479
480/*====================================================================*/
481
482static ssize_t ds_read(struct file *file, char __user *buf,
483 size_t count, loff_t *ppos)
484{
dc109497 485 struct pcmcia_socket *s;
e7a480d2
DB
486 user_info_t *user;
487 int ret;
488
489 ds_dbg(2, "ds_read(socket %d)\n", iminor(file->f_dentry->d_inode));
490
491 if (count < 4)
492 return -EINVAL;
493
494 user = file->private_data;
495 if (CHECK_USER(user))
496 return -EIO;
497
498 s = user->socket;
b5e43913 499 if (s->pcmcia_state.dead)
e7a480d2
DB
500 return -EIO;
501
502 ret = wait_event_interruptible(s->queue, !queue_empty(user));
503 if (ret == 0)
504 ret = put_user(get_queued_event(user), (int __user *)buf) ? -EFAULT : 4;
505
506 return ret;
507} /* ds_read */
508
509/*====================================================================*/
510
511static ssize_t ds_write(struct file *file, const char __user *buf,
512 size_t count, loff_t *ppos)
513{
514 ds_dbg(2, "ds_write(socket %d)\n", iminor(file->f_dentry->d_inode));
515
516 if (count != 4)
517 return -EINVAL;
518 if ((file->f_flags & O_ACCMODE) == O_RDONLY)
519 return -EBADF;
520
521 return -EIO;
522} /* ds_write */
523
524/*====================================================================*/
525
526/* No kernel lock - fine */
527static u_int ds_poll(struct file *file, poll_table *wait)
528{
dc109497 529 struct pcmcia_socket *s;
e7a480d2
DB
530 user_info_t *user;
531
532 ds_dbg(2, "ds_poll(socket %d)\n", iminor(file->f_dentry->d_inode));
533
534 user = file->private_data;
535 if (CHECK_USER(user))
536 return POLLERR;
537 s = user->socket;
538 /*
539 * We don't check for a dead socket here since that
540 * will send cardmgr into an endless spin.
541 */
542 poll_wait(file, &s->queue, wait);
543 if (!queue_empty(user))
544 return POLLIN | POLLRDNORM;
545 return 0;
546} /* ds_poll */
547
548/*====================================================================*/
549
550extern int pcmcia_adjust_resource_info(adjust_t *adj);
551
552static int ds_ioctl(struct inode * inode, struct file * file,
553 u_int cmd, u_long arg)
554{
dc109497 555 struct pcmcia_socket *s;
e7a480d2
DB
556 void __user *uarg = (char __user *)arg;
557 u_int size;
558 int ret, err;
559 ds_ioctl_arg_t *buf;
560 user_info_t *user;
561
562 ds_dbg(2, "ds_ioctl(socket %d, %#x, %#lx)\n", iminor(inode), cmd, arg);
563
564 user = file->private_data;
565 if (CHECK_USER(user))
566 return -EIO;
567
568 s = user->socket;
b5e43913 569 if (s->pcmcia_state.dead)
e7a480d2
DB
570 return -EIO;
571
572 size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
573 if (size > sizeof(ds_ioctl_arg_t)) return -EINVAL;
574
575 /* Permission check */
576 if (!(cmd & IOC_OUT) && !capable(CAP_SYS_ADMIN))
577 return -EPERM;
578
579 if (cmd & IOC_IN) {
580 if (!access_ok(VERIFY_READ, uarg, size)) {
581 ds_dbg(3, "ds_ioctl(): verify_read = %d\n", -EFAULT);
582 return -EFAULT;
583 }
584 }
585 if (cmd & IOC_OUT) {
586 if (!access_ok(VERIFY_WRITE, uarg, size)) {
587 ds_dbg(3, "ds_ioctl(): verify_write = %d\n", -EFAULT);
588 return -EFAULT;
589 }
590 }
591 buf = kmalloc(sizeof(ds_ioctl_arg_t), GFP_KERNEL);
592 if (!buf)
593 return -ENOMEM;
594
595 err = ret = 0;
596
597 if (cmd & IOC_IN) __copy_from_user((char *)buf, uarg, size);
598
599 switch (cmd) {
600 case DS_ADJUST_RESOURCE_INFO:
601 ret = pcmcia_adjust_resource_info(&buf->adjust);
602 break;
e7a480d2
DB
603 case DS_GET_CONFIGURATION_INFO:
604 if (buf->config.Function &&
dc109497 605 (buf->config.Function >= s->functions))
e7a480d2 606 ret = CS_BAD_ARGS;
855cdf13
DB
607 else {
608 struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->config.Function);
f47ad214
DR
609 ret = pccard_get_configuration_info(s, p_dev, &buf->config);
610 pcmcia_put_dev(p_dev);
855cdf13 611 }
e7a480d2
DB
612 break;
613 case DS_GET_FIRST_TUPLE:
7fe908dd 614 mutex_lock(&s->skt_mutex);
dc109497 615 pcmcia_validate_mem(s);
7fe908dd 616 mutex_unlock(&s->skt_mutex);
dc109497 617 ret = pccard_get_first_tuple(s, BIND_FN_ALL, &buf->tuple);
e7a480d2
DB
618 break;
619 case DS_GET_NEXT_TUPLE:
dc109497 620 ret = pccard_get_next_tuple(s, BIND_FN_ALL, &buf->tuple);
e7a480d2
DB
621 break;
622 case DS_GET_TUPLE_DATA:
623 buf->tuple.TupleData = buf->tuple_parse.data;
624 buf->tuple.TupleDataMax = sizeof(buf->tuple_parse.data);
dc109497 625 ret = pccard_get_tuple_data(s, &buf->tuple);
e7a480d2
DB
626 break;
627 case DS_PARSE_TUPLE:
628 buf->tuple.TupleData = buf->tuple_parse.data;
629 ret = pccard_parse_tuple(&buf->tuple, &buf->tuple_parse.parse);
630 break;
631 case DS_RESET_CARD:
dc109497 632 ret = pccard_reset_card(s);
e7a480d2
DB
633 break;
634 case DS_GET_STATUS:
855cdf13
DB
635 if (buf->status.Function &&
636 (buf->status.Function >= s->functions))
637 ret = CS_BAD_ARGS;
638 else {
639 struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->status.Function);
f47ad214
DR
640 ret = pccard_get_status(s, p_dev, &buf->status);
641 pcmcia_put_dev(p_dev);
855cdf13
DB
642 }
643 break;
e7a480d2 644 case DS_VALIDATE_CIS:
7fe908dd 645 mutex_lock(&s->skt_mutex);
dc109497 646 pcmcia_validate_mem(s);
7fe908dd 647 mutex_unlock(&s->skt_mutex);
dc109497 648 ret = pccard_validate_cis(s, BIND_FN_ALL, &buf->cisinfo);
e7a480d2
DB
649 break;
650 case DS_SUSPEND_CARD:
dc109497 651 ret = pcmcia_suspend_card(s);
e7a480d2
DB
652 break;
653 case DS_RESUME_CARD:
dc109497 654 ret = pcmcia_resume_card(s);
e7a480d2
DB
655 break;
656 case DS_EJECT_CARD:
dc109497 657 err = pcmcia_eject_card(s);
e7a480d2
DB
658 break;
659 case DS_INSERT_CARD:
dc109497 660 err = pcmcia_insert_card(s);
e7a480d2
DB
661 break;
662 case DS_ACCESS_CONFIGURATION_REGISTER:
663 if ((buf->conf_reg.Action == CS_WRITE) && !capable(CAP_SYS_ADMIN)) {
664 err = -EPERM;
665 goto free_out;
666 }
855cdf13
DB
667
668 ret = CS_BAD_ARGS;
669
670 if (!(buf->conf_reg.Function &&
671 (buf->conf_reg.Function >= s->functions))) {
672 struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->conf_reg.Function);
73d58588 673 if (p_dev) {
855cdf13 674 ret = pcmcia_access_configuration_register(p_dev, &buf->conf_reg);
73d58588
BH
675 pcmcia_put_dev(p_dev);
676 }
855cdf13 677 }
e7a480d2
DB
678 break;
679 case DS_GET_FIRST_REGION:
680 case DS_GET_NEXT_REGION:
681 case DS_BIND_MTD:
682 if (!capable(CAP_SYS_ADMIN)) {
683 err = -EPERM;
684 goto free_out;
685 } else {
686 static int printed = 0;
687 if (!printed) {
688 printk(KERN_WARNING "2.6. kernels use pcmciamtd instead of memory_cs.c and do not require special\n");
689 printk(KERN_WARNING "MTD handling any more.\n");
690 printed++;
691 }
692 }
693 err = -EINVAL;
694 goto free_out;
695 break;
696 case DS_GET_FIRST_WINDOW:
dc109497 697 ret = pcmcia_get_window(s, &buf->win_info.handle, 0,
e7a480d2
DB
698 &buf->win_info.window);
699 break;
700 case DS_GET_NEXT_WINDOW:
dc109497 701 ret = pcmcia_get_window(s, &buf->win_info.handle,
e7a480d2
DB
702 buf->win_info.handle->index + 1, &buf->win_info.window);
703 break;
704 case DS_GET_MEM_PAGE:
705 ret = pcmcia_get_mem_page(buf->win_info.handle,
706 &buf->win_info.map);
707 break;
708 case DS_REPLACE_CIS:
dc109497 709 ret = pcmcia_replace_cis(s, &buf->cisdump);
e7a480d2
DB
710 break;
711 case DS_BIND_REQUEST:
712 if (!capable(CAP_SYS_ADMIN)) {
713 err = -EPERM;
714 goto free_out;
715 }
716 err = bind_request(s, &buf->bind_info);
717 break;
718 case DS_GET_DEVICE_INFO:
719 err = get_device_info(s, &buf->bind_info, 1);
720 break;
721 case DS_GET_NEXT_DEVICE:
722 err = get_device_info(s, &buf->bind_info, 0);
723 break;
724 case DS_UNBIND_REQUEST:
725 err = 0;
726 break;
727 default:
728 err = -EINVAL;
729 }
730
731 if ((err == 0) && (ret != CS_SUCCESS)) {
732 ds_dbg(2, "ds_ioctl: ret = %d\n", ret);
733 switch (ret) {
734 case CS_BAD_SOCKET: case CS_NO_CARD:
735 err = -ENODEV; break;
736 case CS_BAD_ARGS: case CS_BAD_ATTRIBUTE: case CS_BAD_IRQ:
737 case CS_BAD_TUPLE:
738 err = -EINVAL; break;
739 case CS_IN_USE:
740 err = -EBUSY; break;
741 case CS_OUT_OF_RESOURCE:
742 err = -ENOSPC; break;
743 case CS_NO_MORE_ITEMS:
744 err = -ENODATA; break;
745 case CS_UNSUPPORTED_FUNCTION:
746 err = -ENOSYS; break;
747 default:
748 err = -EIO; break;
749 }
750 }
751
752 if (cmd & IOC_OUT) {
753 if (__copy_to_user(uarg, (char *)buf, size))
754 err = -EFAULT;
755 }
756
757free_out:
758 kfree(buf);
759 return err;
760} /* ds_ioctl */
761
762/*====================================================================*/
763
764static struct file_operations ds_fops = {
765 .owner = THIS_MODULE,
766 .open = ds_open,
767 .release = ds_release,
768 .ioctl = ds_ioctl,
769 .read = ds_read,
770 .write = ds_write,
771 .poll = ds_poll,
772};
773
774void __init pcmcia_setup_ioctl(void) {
775 int i;
776
777 /* Set up character device for user mode clients */
778 i = register_chrdev(0, "pcmcia", &ds_fops);
1a8ceafc 779 if (i < 0)
e7a480d2 780 printk(KERN_NOTICE "unable to find a free device # for "
1a8ceafc 781 "Driver Services (error=%d)\n", i);
e7a480d2
DB
782 else
783 major_dev = i;
784
785#ifdef CONFIG_PROC_FS
786 proc_pccard = proc_mkdir("pccard", proc_bus);
787 if (proc_pccard)
788 create_proc_read_entry("drivers",0,proc_pccard,proc_read_drivers,NULL);
789#endif
790}
791
792
793void __exit pcmcia_cleanup_ioctl(void) {
794#ifdef CONFIG_PROC_FS
795 if (proc_pccard) {
796 remove_proc_entry("drivers", proc_pccard);
797 remove_proc_entry("pccard", proc_bus);
798 }
799#endif
800 if (major_dev != -1)
801 unregister_chrdev(major_dev, "pcmcia");
802}