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