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
21#include <linux/kernel.h>
22#include <linux/module.h>
23#include <linux/init.h>
24#include <linux/major.h>
25#include <linux/errno.h>
26#include <linux/ioctl.h>
27#include <linux/proc_fs.h>
28#include <linux/poll.h>
29#include <linux/pci.h>
30#include <linux/workqueue.h>
31
32#define IN_CARD_SERVICES
33#include <pcmcia/cs_types.h>
34#include <pcmcia/cs.h>
35#include <pcmcia/cistpl.h>
36#include <pcmcia/ds.h>
37#include <pcmcia/ss.h>
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;
56	struct pcmcia_socket	*socket;
57} user_info_t;
58
59
60#ifdef DEBUG
61extern int ds_pc_debug;
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
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}
87
88/* backwards-compatible accessing of driver --- by name! */
89
90static struct pcmcia_driver *get_pcmcia_driver(dev_info_t *dev_info)
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;
130	int rc;
131
132	rc = bus_for_each_drv(&pcmcia_bus_type, NULL,
133			      (void *) &p, proc_read_drivers_callback);
134	if (rc < 0)
135		return rc;
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
167void handle_event(struct pcmcia_socket *s, event_t event)
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
199static int bind_request(struct pcmcia_socket *s, bind_info_t *bind_info)
200{
201	struct pcmcia_driver *p_drv;
202	struct pcmcia_device *p_dev;
203	int ret = 0;
204	unsigned long flags;
205
206	s = pcmcia_get_socket(s);
207	if (!s)
208		return -EINVAL;
209
210	ds_dbg(2, "bind_request(%d, '%s')\n", s->sock,
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);
234					bind_info->instance = p_dev;
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	 */
273	mutex_lock(&s->skt_mutex);
274	ret = bus_rescan_devices(&pcmcia_bus_type);
275	mutex_unlock(&s->skt_mutex);
276	if (ret)
277		goto err_put_module;
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:
291	pcmcia_put_socket(s);
292
293	return (ret);
294} /* bind_request */
295
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;
302
303	return s->cb_dev->subordinate;
304}
305#endif
306
307static int get_device_info(struct pcmcia_socket *s, bind_info_t *bind_info, int first)
308{
309	dev_node_t *node;
310	struct pcmcia_device *p_dev;
311	struct pcmcia_driver *p_drv;
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
323		bus = pcmcia_lookup_bus(s);
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
366	p_drv = to_pcmcia_drv(p_dev->dev.driver);
367	if (p_drv && !p_dev->_locked) {
368		ret = -EAGAIN;
369		goto err_put;
370	}
371
372	if (first)
373		node = p_dev->dev_node;
374	else
375		for (node = p_dev->dev_node; node; node = node->next)
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);
397    struct pcmcia_socket *s;
398    user_info_t *user;
399    static int warning_printed = 0;
400
401    ds_dbg(0, "ds_open(socket %d)\n", i);
402
403    s = pcmcia_get_socket_by_nr(i);
404    if (!s)
405	    return -ENODEV;
406    s = pcmcia_get_socket(s);
407    if (!s)
408	    return -ENODEV;
409
410    if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
411	    if (s->pcmcia_state.busy) {
412		    pcmcia_put_socket(s);
413		    return -EBUSY;
414	    }
415	else
416	    s->pcmcia_state.busy = 1;
417    }
418
419    user = kmalloc(sizeof(user_info_t), GFP_KERNEL);
420    if (!user) {
421	    pcmcia_put_socket(s);
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
431    if (!warning_printed) {
432	    printk(KERN_INFO "pcmcia: Detected deprecated PCMCIA ioctl "
433			"usage from process: %s.\n", current->comm);
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
442    if (s->pcmcia_state.present)
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{
451    struct pcmcia_socket *s;
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) {
464	s->pcmcia_state.busy = 0;
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);
474    pcmcia_put_socket(s);
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{
484    struct pcmcia_socket *s;
485    user_info_t *user;
486    int ret;
487
488    ds_dbg(2, "ds_read(socket %d)\n", iminor(file->f_path.dentry->d_inode));
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;
498    if (s->pcmcia_state.dead)
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{
513    ds_dbg(2, "ds_write(socket %d)\n", iminor(file->f_path.dentry->d_inode));
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{
528    struct pcmcia_socket *s;
529    user_info_t *user;
530
531    ds_dbg(2, "ds_poll(socket %d)\n", iminor(file->f_path.dentry->d_inode));
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{
554    struct pcmcia_socket *s;
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;
568    if (s->pcmcia_state.dead)
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
596    if (cmd & IOC_IN) {
597	if (__copy_from_user((char *)buf, uarg, size)) {
598	    err = -EFAULT;
599	    goto free_out;
600	}
601    }
602
603    switch (cmd) {
604    case DS_ADJUST_RESOURCE_INFO:
605	ret = pcmcia_adjust_resource_info(&buf->adjust);
606	break;
607    case DS_GET_CONFIGURATION_INFO:
608	if (buf->config.Function &&
609	   (buf->config.Function >= s->functions))
610	    ret = CS_BAD_ARGS;
611	else {
612	    struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->config.Function);
613	    ret = pccard_get_configuration_info(s, p_dev, &buf->config);
614	    pcmcia_put_dev(p_dev);
615	}
616	break;
617    case DS_GET_FIRST_TUPLE:
618	mutex_lock(&s->skt_mutex);
619	pcmcia_validate_mem(s);
620	mutex_unlock(&s->skt_mutex);
621	ret = pccard_get_first_tuple(s, BIND_FN_ALL, &buf->tuple);
622	break;
623    case DS_GET_NEXT_TUPLE:
624	ret = pccard_get_next_tuple(s, BIND_FN_ALL, &buf->tuple);
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);
629	ret = pccard_get_tuple_data(s, &buf->tuple);
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:
636	ret = pccard_reset_card(s);
637	break;
638    case DS_GET_STATUS:
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);
644		    ret = pccard_get_status(s, p_dev, &buf->status);
645		    pcmcia_put_dev(p_dev);
646	    }
647	    break;
648    case DS_VALIDATE_CIS:
649	mutex_lock(&s->skt_mutex);
650	pcmcia_validate_mem(s);
651	mutex_unlock(&s->skt_mutex);
652	ret = pccard_validate_cis(s, BIND_FN_ALL, &buf->cisinfo);
653	break;
654    case DS_SUSPEND_CARD:
655	ret = pcmcia_suspend_card(s);
656	break;
657    case DS_RESUME_CARD:
658	ret = pcmcia_resume_card(s);
659	break;
660    case DS_EJECT_CARD:
661	err = pcmcia_eject_card(s);
662	break;
663    case DS_INSERT_CARD:
664	err = pcmcia_insert_card(s);
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	}
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);
677		if (p_dev) {
678			ret = pcmcia_access_configuration_register(p_dev, &buf->conf_reg);
679			pcmcia_put_dev(p_dev);
680		}
681	}
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:
701	ret = pcmcia_get_window(s, &buf->win_info.handle, 0,
702			&buf->win_info.window);
703	break;
704    case DS_GET_NEXT_WINDOW:
705	ret = pcmcia_get_window(s, &buf->win_info.handle,
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:
713	ret = pcmcia_replace_cis(s, &buf->cisdump);
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
768static const struct file_operations ds_fops = {
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);
783	if (i < 0)
784		printk(KERN_NOTICE "unable to find a free device # for "
785		       "Driver Services (error=%d)\n", i);
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}
807