1/*======================================================================
2
3    PC Card Driver Services
4
5    ds.c 1.112 2001/10/13 00:08:28
6
7    The contents of this file are subject to the Mozilla Public
8    License Version 1.1 (the "License"); you may not use this file
9    except in compliance with the License. You may obtain a copy of
10    the License at http://www.mozilla.org/MPL/
11
12    Software distributed under the License is distributed on an "AS
13    IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
14    implied. See the License for the specific language governing
15    rights and limitations under the License.
16
17    The initial developer of the original code is David A. Hinds
18    <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
19    are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
20
21    Alternatively, the contents of this file may be used under the
22    terms of the GNU General Public License version 2 (the "GPL"), in
23    which case the provisions of the GPL are applicable instead of the
24    above.  If you wish to allow the use of your version of this file
25    only under the terms of the GPL and not to allow others to use
26    your version of this file under the MPL, indicate your decision
27    by deleting the provisions above and replace them with the notice
28    and other provisions required by the GPL.  If you do not delete
29    the provisions above, a recipient may use your version of this
30    file under either the MPL or the GPL.
31
32======================================================================*/
33
34#include <linux/config.h>
35#include <linux/module.h>
36#include <linux/init.h>
37#include <linux/kernel.h>
38#include <linux/major.h>
39#include <linux/string.h>
40#include <linux/errno.h>
41#include <linux/slab.h>
42#include <linux/mm.h>
43#include <linux/fcntl.h>
44#include <linux/sched.h>
45#include <linux/smp_lock.h>
46#include <linux/timer.h>
47#include <linux/ioctl.h>
48#include <linux/proc_fs.h>
49#include <linux/poll.h>
50#include <linux/pci.h>
51
52#include <pcmcia/version.h>
53#include <pcmcia/cs_types.h>
54#include <pcmcia/cs.h>
55#include <pcmcia/bulkmem.h>
56#include <pcmcia/cistpl.h>
57#include <pcmcia/ds.h>
58
59/*====================================================================*/
60
61/* Module parameters */
62
63MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
64MODULE_DESCRIPTION("PCMCIA Driver Services " CS_RELEASE);
65MODULE_LICENSE("Dual MPL/GPL");
66
67#define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i")
68
69#ifdef PCMCIA_DEBUG
70INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
71#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
72static const char *version =
73"ds.c 1.112 2001/10/13 00:08:28 (David Hinds)";
74#else
75#define DEBUG(n, args...)
76#endif
77
78/*====================================================================*/
79
80typedef struct driver_info_t {
81    dev_info_t		dev_info;
82    int			use_count, status;
83    dev_link_t		*(*attach)(void);
84    void		(*detach)(dev_link_t *);
85    struct driver_info_t *next;
86} driver_info_t;
87
88typedef struct socket_bind_t {
89    driver_info_t	*driver;
90    u_char		function;
91    dev_link_t		*instance;
92    struct socket_bind_t *next;
93} socket_bind_t;
94
95/* Device user information */
96#define MAX_EVENTS	32
97#define USER_MAGIC	0x7ea4
98#define CHECK_USER(u) \
99    (((u) == NULL) || ((u)->user_magic != USER_MAGIC))
100typedef struct user_info_t {
101    u_int		user_magic;
102    int			event_head, event_tail;
103    event_t		event[MAX_EVENTS];
104    struct user_info_t	*next;
105} user_info_t;
106
107/* Socket state information */
108typedef struct socket_info_t {
109    client_handle_t	handle;
110    int			state;
111    user_info_t		*user;
112    int			req_pending, req_result;
113    wait_queue_head_t	queue, request;
114    struct timer_list	removal;
115    socket_bind_t	*bind;
116} socket_info_t;
117
118#define SOCKET_PRESENT		0x01
119#define SOCKET_BUSY		0x02
120#define SOCKET_REMOVAL_PENDING	0x10
121
122/*====================================================================*/
123
124/* Device driver ID passed to Card Services */
125static dev_info_t dev_info = "Driver Services";
126
127/* Linked list of all registered device drivers */
128static driver_info_t *root_driver = NULL;
129
130static int sockets = 0, major_dev = -1;
131static socket_info_t *socket_table = NULL;
132
133extern struct proc_dir_entry *proc_pccard;
134
135/* We use this to distinguish in-kernel from modular drivers */
136static int init_status = 1;
137
138/*====================================================================*/
139
140static void cs_error(client_handle_t handle, int func, int ret)
141{
142    error_info_t err = { func, ret };
143    pcmcia_report_error(handle, &err);
144}
145
146/*======================================================================
147
148    Register_pccard_driver() and unregister_pccard_driver() are used
149    tell Driver Services that a PC Card client driver is available to
150    be bound to sockets.
151
152======================================================================*/
153
154int register_pccard_driver(dev_info_t *dev_info,
155			   dev_link_t *(*attach)(void),
156			   void (*detach)(dev_link_t *))
157{
158    driver_info_t *driver;
159    socket_bind_t *b;
160    int i;
161
162    DEBUG(0, "ds: register_pccard_driver('%s')\n", (char *)dev_info);
163    for (driver = root_driver; driver; driver = driver->next)
164	if (strncmp((char *)dev_info, (char *)driver->dev_info,
165		    DEV_NAME_LEN) == 0)
166	    break;
167    if (!driver) {
168	driver = kmalloc(sizeof(driver_info_t), GFP_KERNEL);
169	if (!driver) return -ENOMEM;
170	strncpy(driver->dev_info, (char *)dev_info, DEV_NAME_LEN);
171	driver->use_count = 0;
172	driver->status = init_status;
173	driver->next = root_driver;
174	root_driver = driver;
175    }
176
177    driver->attach = attach;
178    driver->detach = detach;
179    if (driver->use_count == 0) return 0;
180
181    /* Instantiate any already-bound devices */
182    for (i = 0; i < sockets; i++)
183	for (b = socket_table[i].bind; b; b = b->next) {
184	    if (b->driver != driver) continue;
185	    b->instance = driver->attach();
186	    if (b->instance == NULL)
187		printk(KERN_NOTICE "ds: unable to create instance "
188		       "of '%s'!\n", driver->dev_info);
189	}
190
191    return 0;
192} /* register_pccard_driver */
193
194/*====================================================================*/
195
196int unregister_pccard_driver(dev_info_t *dev_info)
197{
198    driver_info_t *target, **d = &root_driver;
199    socket_bind_t *b;
200    int i;
201
202    DEBUG(0, "ds: unregister_pccard_driver('%s')\n",
203	  (char *)dev_info);
204    while ((*d) && (strncmp((*d)->dev_info, (char *)dev_info,
205			    DEV_NAME_LEN) != 0))
206	d = &(*d)->next;
207    if (*d == NULL)
208	return -ENODEV;
209
210    target = *d;
211    if (target->use_count == 0) {
212	*d = target->next;
213	kfree(target);
214    } else {
215	/* Blank out any left-over device instances */
216	target->attach = NULL; target->detach = NULL;
217	for (i = 0; i < sockets; i++)
218	    for (b = socket_table[i].bind; b; b = b->next)
219		if (b->driver == target) b->instance = NULL;
220    }
221    return 0;
222} /* unregister_pccard_driver */
223
224/*====================================================================*/
225
226#ifdef CONFIG_PROC_FS
227static int proc_read_drivers(char *buf, char **start, off_t pos,
228			     int count, int *eof, void *data)
229{
230    driver_info_t *d;
231    char *p = buf;
232    for (d = root_driver; d; d = d->next)
233	p += sprintf(p, "%-24.24s %d %d\n", d->dev_info,
234		     d->status, d->use_count);
235    return (p - buf);
236}
237#endif
238
239/*======================================================================
240
241    These manage a ring buffer of events pending for one user process
242
243======================================================================*/
244
245static int queue_empty(user_info_t *user)
246{
247    return (user->event_head == user->event_tail);
248}
249
250static event_t get_queued_event(user_info_t *user)
251{
252    user->event_tail = (user->event_tail+1) % MAX_EVENTS;
253    return user->event[user->event_tail];
254}
255
256static void queue_event(user_info_t *user, event_t event)
257{
258    user->event_head = (user->event_head+1) % MAX_EVENTS;
259    if (user->event_head == user->event_tail)
260	user->event_tail = (user->event_tail+1) % MAX_EVENTS;
261    user->event[user->event_head] = event;
262}
263
264static void handle_event(socket_info_t *s, event_t event)
265{
266    user_info_t *user;
267    for (user = s->user; user; user = user->next)
268	queue_event(user, event);
269    wake_up_interruptible(&s->queue);
270}
271
272static int handle_request(socket_info_t *s, event_t event)
273{
274    if (s->req_pending != 0)
275	return CS_IN_USE;
276    if (s->state & SOCKET_BUSY)
277	s->req_pending = 1;
278    handle_event(s, event);
279    if (s->req_pending > 0) {
280	interruptible_sleep_on(&s->request);
281	if (signal_pending(current))
282	    return CS_IN_USE;
283	else
284	    return s->req_result;
285    }
286    return CS_SUCCESS;
287}
288
289static void handle_removal(u_long sn)
290{
291    socket_info_t *s = &socket_table[sn];
292    handle_event(s, CS_EVENT_CARD_REMOVAL);
293    s->state &= ~SOCKET_REMOVAL_PENDING;
294}
295
296/*======================================================================
297
298    The card status event handler.
299
300======================================================================*/
301
302static int ds_event(event_t event, int priority,
303		    event_callback_args_t *args)
304{
305    socket_info_t *s;
306    int i;
307
308    DEBUG(1, "ds: ds_event(0x%06x, %d, 0x%p)\n",
309	  event, priority, args->client_handle);
310    s = args->client_data;
311    i = s - socket_table;
312
313    switch (event) {
314
315    case CS_EVENT_CARD_REMOVAL:
316	s->state &= ~SOCKET_PRESENT;
317	if (!(s->state & SOCKET_REMOVAL_PENDING)) {
318	    s->state |= SOCKET_REMOVAL_PENDING;
319	    s->removal.expires = jiffies + HZ/10;
320	    add_timer(&s->removal);
321	}
322	break;
323
324    case CS_EVENT_CARD_INSERTION:
325	s->state |= SOCKET_PRESENT;
326	handle_event(s, event);
327	break;
328
329    case CS_EVENT_EJECTION_REQUEST:
330	return handle_request(s, event);
331	break;
332
333    default:
334	handle_event(s, event);
335	break;
336    }
337
338    return 0;
339} /* ds_event */
340
341/*======================================================================
342
343    bind_mtd() connects a memory region with an MTD client.
344
345======================================================================*/
346
347static int bind_mtd(int i, mtd_info_t *mtd_info)
348{
349    mtd_bind_t bind_req;
350    int ret;
351
352    bind_req.dev_info = &mtd_info->dev_info;
353    bind_req.Attributes = mtd_info->Attributes;
354    bind_req.Socket = i;
355    bind_req.CardOffset = mtd_info->CardOffset;
356    ret = pcmcia_bind_mtd(&bind_req);
357    if (ret != CS_SUCCESS) {
358	cs_error(NULL, BindMTD, ret);
359	printk(KERN_NOTICE "ds: unable to bind MTD '%s' to socket %d"
360	       " offset 0x%x\n",
361	       (char *)bind_req.dev_info, i, bind_req.CardOffset);
362	return -ENODEV;
363    }
364    return 0;
365} /* bind_mtd */
366
367/*======================================================================
368
369    bind_request() connects a socket to a particular client driver.
370    It looks up the specified device ID in the list of registered
371    drivers, binds it to the socket, and tries to create an instance
372    of the device.  unbind_request() deletes a driver instance.
373
374======================================================================*/
375
376static int bind_request(int i, bind_info_t *bind_info)
377{
378    struct driver_info_t *driver;
379    socket_bind_t *b;
380    bind_req_t bind_req;
381    socket_info_t *s = &socket_table[i];
382    int ret;
383
384    DEBUG(2, "bind_request(%d, '%s')\n", i,
385	  (char *)bind_info->dev_info);
386    for (driver = root_driver; driver; driver = driver->next)
387	if (strcmp((char *)driver->dev_info,
388		   (char *)bind_info->dev_info) == 0)
389	    break;
390    if (driver == NULL) {
391	driver = kmalloc(sizeof(driver_info_t), GFP_KERNEL);
392	if (!driver) return -ENOMEM;
393	strncpy(driver->dev_info, bind_info->dev_info, DEV_NAME_LEN);
394	driver->use_count = 0;
395	driver->next = root_driver;
396	driver->attach = NULL; driver->detach = NULL;
397	root_driver = driver;
398    }
399
400    for (b = s->bind; b; b = b->next)
401	if ((driver == b->driver) &&
402	    (bind_info->function == b->function))
403	    break;
404    if (b != NULL) {
405	bind_info->instance = b->instance;
406	return -EBUSY;
407    }
408
409    bind_req.Socket = i;
410    bind_req.Function = bind_info->function;
411    bind_req.dev_info = &driver->dev_info;
412    ret = pcmcia_bind_device(&bind_req);
413    if (ret != CS_SUCCESS) {
414	cs_error(NULL, BindDevice, ret);
415	printk(KERN_NOTICE "ds: unable to bind '%s' to socket %d\n",
416	       (char *)dev_info, i);
417	return -ENODEV;
418    }
419
420    /* Add binding to list for this socket */
421    driver->use_count++;
422    b = kmalloc(sizeof(socket_bind_t), GFP_KERNEL);
423    if (!b)
424    {
425    	driver->use_count--;
426	return -ENOMEM;
427    }
428    b->driver = driver;
429    b->function = bind_info->function;
430    b->instance = NULL;
431    b->next = s->bind;
432    s->bind = b;
433
434    if (driver->attach) {
435	b->instance = driver->attach();
436	if (b->instance == NULL) {
437	    printk(KERN_NOTICE "ds: unable to create instance "
438		   "of '%s'!\n", (char *)bind_info->dev_info);
439	    return -ENODEV;
440	}
441    }
442
443    return 0;
444} /* bind_request */
445
446/*====================================================================*/
447
448static int get_device_info(int i, bind_info_t *bind_info, int first)
449{
450    socket_info_t *s = &socket_table[i];
451    socket_bind_t *b;
452    dev_node_t *node;
453
454#ifdef CONFIG_CARDBUS
455    /*
456     * Some unbelievably ugly code to associate the PCI cardbus
457     * device and its driver with the PCMCIA "bind" information.
458     */
459    {
460	struct pci_bus *bus;
461
462	bus = pcmcia_lookup_bus(s->handle);
463	if (bus) {
464	    	struct list_head *list;
465		struct pci_dev *dev = NULL;
466
467		list = bus->devices.next;
468		while (list != &bus->devices) {
469			struct pci_dev *pdev = pci_dev_b(list);
470			list = list->next;
471
472			if (first) {
473				dev = pdev;
474				break;
475			}
476
477			/* Try to handle "next" here some way? */
478		}
479		if (dev && dev->driver) {
480			strncpy(bind_info->name, dev->driver->name, DEV_NAME_LEN);
481			bind_info->name[DEV_NAME_LEN-1] = '\0';
482			bind_info->major = 0;
483			bind_info->minor = 0;
484			bind_info->next = NULL;
485			return 0;
486		}
487	}
488    }
489#endif
490
491    for (b = s->bind; b; b = b->next)
492	if ((strcmp((char *)b->driver->dev_info,
493		    (char *)bind_info->dev_info) == 0) &&
494	    (b->function == bind_info->function))
495	    break;
496    if (b == NULL) return -ENODEV;
497    if ((b->instance == NULL) ||
498	(b->instance->state & DEV_CONFIG_PENDING))
499	return -EAGAIN;
500    if (first)
501	node = b->instance->dev;
502    else
503	for (node = b->instance->dev; node; node = node->next)
504	    if (node == bind_info->next) break;
505    if (node == NULL) return -ENODEV;
506
507    strncpy(bind_info->name, node->dev_name, DEV_NAME_LEN);
508    bind_info->name[DEV_NAME_LEN-1] = '\0';
509    bind_info->major = node->major;
510    bind_info->minor = node->minor;
511    bind_info->next = node->next;
512
513    return 0;
514} /* get_device_info */
515
516/*====================================================================*/
517
518static int unbind_request(int i, bind_info_t *bind_info)
519{
520    socket_info_t *s = &socket_table[i];
521    socket_bind_t **b, *c;
522
523    DEBUG(2, "unbind_request(%d, '%s')\n", i,
524	  (char *)bind_info->dev_info);
525    for (b = &s->bind; *b; b = &(*b)->next)
526	if ((strcmp((char *)(*b)->driver->dev_info,
527		    (char *)bind_info->dev_info) == 0) &&
528	    ((*b)->function == bind_info->function))
529	    break;
530    if (*b == NULL)
531	return -ENODEV;
532
533    c = *b;
534    c->driver->use_count--;
535    if (c->driver->detach) {
536	if (c->instance)
537	    c->driver->detach(c->instance);
538    } else {
539	if (c->driver->use_count == 0) {
540	    driver_info_t **d;
541	    for (d = &root_driver; *d; d = &((*d)->next))
542		if (c->driver == *d) break;
543	    *d = (*d)->next;
544	    kfree(c->driver);
545	}
546    }
547    *b = c->next;
548    kfree(c);
549
550    return 0;
551} /* unbind_request */
552
553/*======================================================================
554
555    The user-mode PC Card device interface
556
557======================================================================*/
558
559static int ds_open(struct inode *inode, struct file *file)
560{
561    socket_t i = MINOR(inode->i_rdev);
562    socket_info_t *s;
563    user_info_t *user;
564
565    DEBUG(0, "ds_open(socket %d)\n", i);
566    if ((i >= sockets) || (sockets == 0))
567	return -ENODEV;
568    s = &socket_table[i];
569    if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
570	if (s->state & SOCKET_BUSY)
571	    return -EBUSY;
572	else
573	    s->state |= SOCKET_BUSY;
574    }
575
576    user = kmalloc(sizeof(user_info_t), GFP_KERNEL);
577    if (!user) return -ENOMEM;
578    user->event_tail = user->event_head = 0;
579    user->next = s->user;
580    user->user_magic = USER_MAGIC;
581    s->user = user;
582    file->private_data = user;
583
584    if (s->state & SOCKET_PRESENT)
585	queue_event(user, CS_EVENT_CARD_INSERTION);
586    return 0;
587} /* ds_open */
588
589/*====================================================================*/
590
591static int ds_release(struct inode *inode, struct file *file)
592{
593    socket_t i = MINOR(inode->i_rdev);
594    socket_info_t *s;
595    user_info_t *user, **link;
596
597    DEBUG(0, "ds_release(socket %d)\n", i);
598    if ((i >= sockets) || (sockets == 0))
599	return 0;
600    lock_kernel();
601    s = &socket_table[i];
602    user = file->private_data;
603    if (CHECK_USER(user))
604	goto out;
605
606    /* Unlink user data structure */
607    if ((file->f_flags & O_ACCMODE) != O_RDONLY)
608	s->state &= ~SOCKET_BUSY;
609    file->private_data = NULL;
610    for (link = &s->user; *link; link = &(*link)->next)
611	if (*link == user) break;
612    if (link == NULL)
613	goto out;
614    *link = user->next;
615    user->user_magic = 0;
616    kfree(user);
617out:
618    unlock_kernel();
619    return 0;
620} /* ds_release */
621
622/*====================================================================*/
623
624static ssize_t ds_read(struct file *file, char *buf,
625		       size_t count, loff_t *ppos)
626{
627    socket_t i = MINOR(file->f_dentry->d_inode->i_rdev);
628    socket_info_t *s;
629    user_info_t *user;
630
631    DEBUG(2, "ds_read(socket %d)\n", i);
632
633    if ((i >= sockets) || (sockets == 0))
634	return -ENODEV;
635    if (count < 4)
636	return -EINVAL;
637    s = &socket_table[i];
638    user = file->private_data;
639    if (CHECK_USER(user))
640	return -EIO;
641
642    if (queue_empty(user)) {
643	interruptible_sleep_on(&s->queue);
644	if (signal_pending(current))
645	    return -EINTR;
646    }
647
648    return put_user(get_queued_event(user), (int *)buf) ? -EFAULT : 4;
649} /* ds_read */
650
651/*====================================================================*/
652
653static ssize_t ds_write(struct file *file, const char *buf,
654			size_t count, loff_t *ppos)
655{
656    socket_t i = MINOR(file->f_dentry->d_inode->i_rdev);
657    socket_info_t *s;
658    user_info_t *user;
659
660    DEBUG(2, "ds_write(socket %d)\n", i);
661
662    if ((i >= sockets) || (sockets == 0))
663	return -ENODEV;
664    if (count != 4)
665	return -EINVAL;
666    if ((file->f_flags & O_ACCMODE) == O_RDONLY)
667	return -EBADF;
668    s = &socket_table[i];
669    user = file->private_data;
670    if (CHECK_USER(user))
671	return -EIO;
672
673    if (s->req_pending) {
674	s->req_pending--;
675	get_user(s->req_result, (int *)buf);
676	if ((s->req_result != 0) || (s->req_pending == 0))
677	    wake_up_interruptible(&s->request);
678    } else
679	return -EIO;
680
681    return 4;
682} /* ds_write */
683
684/*====================================================================*/
685
686/* No kernel lock - fine */
687static u_int ds_poll(struct file *file, poll_table *wait)
688{
689    socket_t i = MINOR(file->f_dentry->d_inode->i_rdev);
690    socket_info_t *s;
691    user_info_t *user;
692
693    DEBUG(2, "ds_poll(socket %d)\n", i);
694
695    if ((i >= sockets) || (sockets == 0))
696	return POLLERR;
697    s = &socket_table[i];
698    user = file->private_data;
699    if (CHECK_USER(user))
700	return POLLERR;
701    poll_wait(file, &s->queue, wait);
702    if (!queue_empty(user))
703	return POLLIN | POLLRDNORM;
704    return 0;
705} /* ds_poll */
706
707/*====================================================================*/
708
709static int ds_ioctl(struct inode * inode, struct file * file,
710		    u_int cmd, u_long arg)
711{
712    socket_t i = MINOR(inode->i_rdev);
713    socket_info_t *s;
714    u_int size;
715    int ret, err;
716    ds_ioctl_arg_t buf;
717
718    DEBUG(2, "ds_ioctl(socket %d, %#x, %#lx)\n", i, cmd, arg);
719
720    if ((i >= sockets) || (sockets == 0))
721	return -ENODEV;
722    s = &socket_table[i];
723
724    size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
725    if (size > sizeof(ds_ioctl_arg_t)) return -EINVAL;
726
727    /* Permission check */
728    if (!(cmd & IOC_OUT) && !capable(CAP_SYS_ADMIN))
729	return -EPERM;
730
731    if (cmd & IOC_IN) {
732	err = verify_area(VERIFY_READ, (char *)arg, size);
733	if (err) {
734	    DEBUG(3, "ds_ioctl(): verify_read = %d\n", err);
735	    return err;
736	}
737    }
738    if (cmd & IOC_OUT) {
739	err = verify_area(VERIFY_WRITE, (char *)arg, size);
740	if (err) {
741	    DEBUG(3, "ds_ioctl(): verify_write = %d\n", err);
742	    return err;
743	}
744    }
745
746    err = ret = 0;
747
748    if (cmd & IOC_IN) copy_from_user((char *)&buf, (char *)arg, size);
749
750    switch (cmd) {
751    case DS_ADJUST_RESOURCE_INFO:
752	ret = pcmcia_adjust_resource_info(s->handle, &buf.adjust);
753	break;
754    case DS_GET_CARD_SERVICES_INFO:
755	ret = pcmcia_get_card_services_info(&buf.servinfo);
756	break;
757    case DS_GET_CONFIGURATION_INFO:
758	ret = pcmcia_get_configuration_info(s->handle, &buf.config);
759	break;
760    case DS_GET_FIRST_TUPLE:
761	ret = pcmcia_get_first_tuple(s->handle, &buf.tuple);
762	break;
763    case DS_GET_NEXT_TUPLE:
764	ret = pcmcia_get_next_tuple(s->handle, &buf.tuple);
765	break;
766    case DS_GET_TUPLE_DATA:
767	buf.tuple.TupleData = buf.tuple_parse.data;
768	buf.tuple.TupleDataMax = sizeof(buf.tuple_parse.data);
769	ret = pcmcia_get_tuple_data(s->handle, &buf.tuple);
770	break;
771    case DS_PARSE_TUPLE:
772	buf.tuple.TupleData = buf.tuple_parse.data;
773	ret = pcmcia_parse_tuple(s->handle, &buf.tuple, &buf.tuple_parse.parse);
774	break;
775    case DS_RESET_CARD:
776	ret = pcmcia_reset_card(s->handle, NULL);
777	break;
778    case DS_GET_STATUS:
779	ret = pcmcia_get_status(s->handle, &buf.status);
780	break;
781    case DS_VALIDATE_CIS:
782	ret = pcmcia_validate_cis(s->handle, &buf.cisinfo);
783	break;
784    case DS_SUSPEND_CARD:
785	ret = pcmcia_suspend_card(s->handle, NULL);
786	break;
787    case DS_RESUME_CARD:
788	ret = pcmcia_resume_card(s->handle, NULL);
789	break;
790    case DS_EJECT_CARD:
791	ret = pcmcia_eject_card(s->handle, NULL);
792	break;
793    case DS_INSERT_CARD:
794	ret = pcmcia_insert_card(s->handle, NULL);
795	break;
796    case DS_ACCESS_CONFIGURATION_REGISTER:
797	if ((buf.conf_reg.Action == CS_WRITE) && !capable(CAP_SYS_ADMIN))
798	    return -EPERM;
799	ret = pcmcia_access_configuration_register(s->handle, &buf.conf_reg);
800	break;
801    case DS_GET_FIRST_REGION:
802        ret = pcmcia_get_first_region(s->handle, &buf.region);
803	break;
804    case DS_GET_NEXT_REGION:
805	ret = pcmcia_get_next_region(s->handle, &buf.region);
806	break;
807    case DS_GET_FIRST_WINDOW:
808	buf.win_info.handle = (window_handle_t)s->handle;
809	ret = pcmcia_get_first_window(&buf.win_info.handle, &buf.win_info.window);
810	break;
811    case DS_GET_NEXT_WINDOW:
812	ret = pcmcia_get_next_window(&buf.win_info.handle, &buf.win_info.window);
813	break;
814    case DS_GET_MEM_PAGE:
815	ret = pcmcia_get_mem_page(buf.win_info.handle,
816			   &buf.win_info.map);
817	break;
818    case DS_REPLACE_CIS:
819	ret = pcmcia_replace_cis(s->handle, &buf.cisdump);
820	break;
821    case DS_BIND_REQUEST:
822	if (!capable(CAP_SYS_ADMIN)) return -EPERM;
823	err = bind_request(i, &buf.bind_info);
824	break;
825    case DS_GET_DEVICE_INFO:
826	err = get_device_info(i, &buf.bind_info, 1);
827	break;
828    case DS_GET_NEXT_DEVICE:
829	err = get_device_info(i, &buf.bind_info, 0);
830	break;
831    case DS_UNBIND_REQUEST:
832	err = unbind_request(i, &buf.bind_info);
833	break;
834    case DS_BIND_MTD:
835	if (!suser()) return -EPERM;
836	err = bind_mtd(i, &buf.mtd_info);
837	break;
838    default:
839	err = -EINVAL;
840    }
841
842    if ((err == 0) && (ret != CS_SUCCESS)) {
843	DEBUG(2, "ds_ioctl: ret = %d\n", ret);
844	switch (ret) {
845	case CS_BAD_SOCKET: case CS_NO_CARD:
846	    err = -ENODEV; break;
847	case CS_BAD_ARGS: case CS_BAD_ATTRIBUTE: case CS_BAD_IRQ:
848	case CS_BAD_TUPLE:
849	    err = -EINVAL; break;
850	case CS_IN_USE:
851	    err = -EBUSY; break;
852	case CS_OUT_OF_RESOURCE:
853	    err = -ENOSPC; break;
854	case CS_NO_MORE_ITEMS:
855	    err = -ENODATA; break;
856	case CS_UNSUPPORTED_FUNCTION:
857	    err = -ENOSYS; break;
858	default:
859	    err = -EIO; break;
860	}
861    }
862
863    if (cmd & IOC_OUT) copy_to_user((char *)arg, (char *)&buf, size);
864
865    return err;
866} /* ds_ioctl */
867
868/*====================================================================*/
869
870static struct file_operations ds_fops = {
871	owner:		THIS_MODULE,
872	open:		ds_open,
873	release:	ds_release,
874	ioctl:		ds_ioctl,
875	read:		ds_read,
876	write:		ds_write,
877	poll:		ds_poll,
878};
879
880EXPORT_SYMBOL(register_pccard_driver);
881EXPORT_SYMBOL(unregister_pccard_driver);
882
883/*====================================================================*/
884
885int __init init_pcmcia_ds(void)
886{
887    client_reg_t client_reg;
888    servinfo_t serv;
889    bind_req_t bind;
890    socket_info_t *s;
891    int i, ret;
892
893    DEBUG(0, "%s\n", version);
894
895    /*
896     * Ugly. But we want to wait for the socket threads to have started up.
897     * We really should let the drivers themselves drive some of this..
898     */
899    current->state = TASK_INTERRUPTIBLE;
900    schedule_timeout(HZ/10);
901
902    pcmcia_get_card_services_info(&serv);
903    if (serv.Revision != CS_RELEASE_CODE) {
904	printk(KERN_NOTICE "ds: Card Services release does not match!\n");
905	return -1;
906    }
907    if (serv.Count == 0) {
908	printk(KERN_NOTICE "ds: no socket drivers loaded!\n");
909	return -1;
910    }
911
912    sockets = serv.Count;
913    socket_table = kmalloc(sockets*sizeof(socket_info_t), GFP_KERNEL);
914    if (!socket_table) return -1;
915    for (i = 0, s = socket_table; i < sockets; i++, s++) {
916	s->state = 0;
917	s->user = NULL;
918	s->req_pending = 0;
919	init_waitqueue_head(&s->queue);
920	init_waitqueue_head(&s->request);
921	s->handle = NULL;
922	init_timer(&s->removal);
923	s->removal.data = i;
924	s->removal.function = &handle_removal;
925	s->bind = NULL;
926    }
927
928    /* Set up hotline to Card Services */
929    client_reg.dev_info = bind.dev_info = &dev_info;
930    client_reg.Attributes = INFO_MASTER_CLIENT;
931    client_reg.EventMask =
932	CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
933	CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
934	CS_EVENT_EJECTION_REQUEST | CS_EVENT_INSERTION_REQUEST |
935        CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
936    client_reg.event_handler = &ds_event;
937    client_reg.Version = 0x0210;
938    for (i = 0; i < sockets; i++) {
939	bind.Socket = i;
940	bind.Function = BIND_FN_ALL;
941	ret = pcmcia_bind_device(&bind);
942	if (ret != CS_SUCCESS) {
943	    cs_error(NULL, BindDevice, ret);
944	    break;
945	}
946	client_reg.event_callback_args.client_data = &socket_table[i];
947	ret = pcmcia_register_client(&socket_table[i].handle,
948			   &client_reg);
949	if (ret != CS_SUCCESS) {
950	    cs_error(NULL, RegisterClient, ret);
951	    break;
952	}
953    }
954
955    /* Set up character device for user mode clients */
956    i = register_chrdev(0, "pcmcia", &ds_fops);
957    if (i == -EBUSY)
958	printk(KERN_NOTICE "unable to find a free device # for "
959	       "Driver Services\n");
960    else
961	major_dev = i;
962
963#ifdef CONFIG_PROC_FS
964    if (proc_pccard)
965	create_proc_read_entry("drivers",0,proc_pccard,proc_read_drivers,NULL);
966    init_status = 0;
967#endif
968    return 0;
969}
970
971#ifdef MODULE
972
973int __init init_module(void)
974{
975    return init_pcmcia_ds();
976}
977
978void __exit cleanup_module(void)
979{
980    int i;
981#ifdef CONFIG_PROC_FS
982    if (proc_pccard)
983	remove_proc_entry("drivers", proc_pccard);
984#endif
985    if (major_dev != -1)
986	unregister_chrdev(major_dev, "pcmcia");
987    for (i = 0; i < sockets; i++)
988	pcmcia_deregister_client(socket_table[i].handle);
989    sockets = 0;
990    kfree(socket_table);
991}
992
993#endif
994