1 /*======================================================================
3 PC Card Driver Services
5 ds.c 1.108 2000/08/07 19:06:15
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/
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.
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.
21 Alternatively, the contents of this file may be used under the
22 terms of the GNU Public License version 2 (the "GPL"), in which
23 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.
32 ======================================================================*/
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/malloc.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>
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>
60 int pc_debug
= PCMCIA_DEBUG
;
61 MODULE_PARM(pc_debug
, "i");
62 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
63 static const char *version
=
64 "ds.c 1.108 2000/08/07 19:06:15 (David Hinds)";
66 #define DEBUG(n, args...)
69 MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
70 MODULE_DESCRIPTION("PCMCIA Driver Services " CS_RELEASE
);
72 /*====================================================================*/
74 typedef struct driver_info_t
{
76 int use_count
, status
;
77 dev_link_t
*(*attach
)(void);
78 void (*detach
)(dev_link_t
*);
79 struct driver_info_t
*next
;
82 typedef struct socket_bind_t
{
83 driver_info_t
*driver
;
86 struct socket_bind_t
*next
;
89 /* Device user information */
91 #define USER_MAGIC 0x7ea4
92 #define CHECK_USER(u) \
93 (((u) == NULL) || ((u)->user_magic != USER_MAGIC))
94 typedef struct user_info_t
{
96 int event_head
, event_tail
;
97 event_t event
[MAX_EVENTS
];
98 struct user_info_t
*next
;
101 /* Socket state information */
102 typedef struct socket_info_t
{
103 client_handle_t handle
;
106 int req_pending
, req_result
;
107 wait_queue_head_t queue
, request
;
108 struct timer_list removal
;
112 #define SOCKET_PRESENT 0x01
113 #define SOCKET_BUSY 0x02
114 #define SOCKET_REMOVAL_PENDING 0x10
116 /*====================================================================*/
118 /* Device driver ID passed to Card Services */
119 static dev_info_t dev_info
= "Driver Services";
121 /* Linked list of all registered device drivers */
122 static driver_info_t
*root_driver
= NULL
;
124 static int sockets
= 0, major_dev
= -1;
125 static socket_info_t
*socket_table
= NULL
;
127 extern struct proc_dir_entry
*proc_pccard
;
129 /* We use this to distinguish in-kernel from modular drivers */
130 static int init_status
= 1;
132 /*====================================================================*/
134 static void cs_error(client_handle_t handle
, int func
, int ret
)
136 error_info_t err
= { func
, ret
};
137 pcmcia_report_error(handle
, &err
);
140 /*======================================================================
142 Register_pccard_driver() and unregister_pccard_driver() are used
143 tell Driver Services that a PC Card client driver is available to
146 ======================================================================*/
148 int register_pccard_driver(dev_info_t
*dev_info
,
149 dev_link_t
*(*attach
)(void),
150 void (*detach
)(dev_link_t
*))
152 driver_info_t
*driver
;
156 DEBUG(0, "ds: register_pccard_driver('%s')\n", (char *)dev_info
);
157 for (driver
= root_driver
; driver
; driver
= driver
->next
)
158 if (strncmp((char *)dev_info
, (char *)driver
->dev_info
,
162 driver
= kmalloc(sizeof(driver_info_t
), GFP_KERNEL
);
163 if (!driver
) return -ENOMEM
;
164 strncpy(driver
->dev_info
, (char *)dev_info
, DEV_NAME_LEN
);
165 driver
->use_count
= 0;
166 driver
->status
= init_status
;
167 driver
->next
= root_driver
;
168 root_driver
= driver
;
171 driver
->attach
= attach
;
172 driver
->detach
= detach
;
173 if (driver
->use_count
== 0) return 0;
175 /* Instantiate any already-bound devices */
176 for (i
= 0; i
< sockets
; i
++)
177 for (b
= socket_table
[i
].bind
; b
; b
= b
->next
) {
178 if (b
->driver
!= driver
) continue;
179 b
->instance
= driver
->attach();
180 if (b
->instance
== NULL
)
181 printk(KERN_NOTICE
"ds: unable to create instance "
182 "of '%s'!\n", driver
->dev_info
);
186 } /* register_pccard_driver */
188 /*====================================================================*/
190 int unregister_pccard_driver(dev_info_t
*dev_info
)
192 driver_info_t
*target
, **d
= &root_driver
;
196 DEBUG(0, "ds: unregister_pccard_driver('%s')\n",
198 while ((*d
) && (strncmp((*d
)->dev_info
, (char *)dev_info
,
205 if (target
->use_count
== 0) {
209 /* Blank out any left-over device instances */
210 target
->attach
= NULL
; target
->detach
= NULL
;
211 for (i
= 0; i
< sockets
; i
++)
212 for (b
= socket_table
[i
].bind
; b
; b
= b
->next
)
213 if (b
->driver
== target
) b
->instance
= NULL
;
216 } /* unregister_pccard_driver */
218 /*====================================================================*/
220 #ifdef CONFIG_PROC_FS
221 static int proc_read_drivers(char *buf
, char **start
, off_t pos
,
222 int count
, int *eof
, void *data
)
226 for (d
= root_driver
; d
; d
= d
->next
)
227 p
+= sprintf(p
, "%-24.24s %d %d\n", d
->dev_info
,
228 d
->status
, d
->use_count
);
233 /*======================================================================
235 These manage a ring buffer of events pending for one user process
237 ======================================================================*/
239 static int queue_empty(user_info_t
*user
)
241 return (user
->event_head
== user
->event_tail
);
244 static event_t
get_queued_event(user_info_t
*user
)
246 user
->event_tail
= (user
->event_tail
+1) % MAX_EVENTS
;
247 return user
->event
[user
->event_tail
];
250 static void queue_event(user_info_t
*user
, event_t event
)
252 user
->event_head
= (user
->event_head
+1) % MAX_EVENTS
;
253 if (user
->event_head
== user
->event_tail
)
254 user
->event_tail
= (user
->event_tail
+1) % MAX_EVENTS
;
255 user
->event
[user
->event_head
] = event
;
258 static void handle_event(socket_info_t
*s
, event_t event
)
261 for (user
= s
->user
; user
; user
= user
->next
)
262 queue_event(user
, event
);
263 wake_up_interruptible(&s
->queue
);
266 static int handle_request(socket_info_t
*s
, event_t event
)
268 if (s
->req_pending
!= 0)
270 if (s
->state
& SOCKET_BUSY
)
272 handle_event(s
, event
);
273 if (s
->req_pending
> 0) {
274 interruptible_sleep_on(&s
->request
);
275 if (signal_pending(current
))
278 return s
->req_result
;
283 static void handle_removal(u_long sn
)
285 socket_info_t
*s
= &socket_table
[sn
];
286 handle_event(s
, CS_EVENT_CARD_REMOVAL
);
287 s
->state
&= ~SOCKET_REMOVAL_PENDING
;
290 /*======================================================================
292 The card status event handler.
294 ======================================================================*/
296 static int ds_event(event_t event
, int priority
,
297 event_callback_args_t
*args
)
302 DEBUG(1, "ds: ds_event(0x%06x, %d, 0x%p)\n",
303 event
, priority
, args
->client_handle
);
304 s
= args
->client_data
;
305 i
= s
- socket_table
;
309 case CS_EVENT_CARD_REMOVAL
:
310 s
->state
&= ~SOCKET_PRESENT
;
311 if (!(s
->state
& SOCKET_REMOVAL_PENDING
)) {
312 s
->state
|= SOCKET_REMOVAL_PENDING
;
313 s
->removal
.expires
= jiffies
+ HZ
/10;
314 add_timer(&s
->removal
);
318 case CS_EVENT_CARD_INSERTION
:
319 s
->state
|= SOCKET_PRESENT
;
320 handle_event(s
, event
);
323 case CS_EVENT_EJECTION_REQUEST
:
324 return handle_request(s
, event
);
328 handle_event(s
, event
);
335 /*======================================================================
337 bind_mtd() connects a memory region with an MTD client.
339 ======================================================================*/
341 static int bind_mtd(int i
, mtd_info_t
*mtd_info
)
346 bind_req
.dev_info
= &mtd_info
->dev_info
;
347 bind_req
.Attributes
= mtd_info
->Attributes
;
349 bind_req
.CardOffset
= mtd_info
->CardOffset
;
350 ret
= pcmcia_bind_mtd(&bind_req
);
351 if (ret
!= CS_SUCCESS
) {
352 cs_error(NULL
, BindMTD
, ret
);
353 printk(KERN_NOTICE
"ds: unable to bind MTD '%s' to socket %d"
355 (char *)bind_req
.dev_info
, i
, bind_req
.CardOffset
);
361 /*======================================================================
363 bind_request() connects a socket to a particular client driver.
364 It looks up the specified device ID in the list of registered
365 drivers, binds it to the socket, and tries to create an instance
366 of the device. unbind_request() deletes a driver instance.
368 ======================================================================*/
370 static int bind_request(int i
, bind_info_t
*bind_info
)
372 struct driver_info_t
*driver
;
375 socket_info_t
*s
= &socket_table
[i
];
378 DEBUG(2, "bind_request(%d, '%s')\n", i
,
379 (char *)bind_info
->dev_info
);
380 for (driver
= root_driver
; driver
; driver
= driver
->next
)
381 if (strcmp((char *)driver
->dev_info
,
382 (char *)bind_info
->dev_info
) == 0)
384 if (driver
== NULL
) {
385 driver
= kmalloc(sizeof(driver_info_t
), GFP_KERNEL
);
386 if (!driver
) return -ENOMEM
;
387 strncpy(driver
->dev_info
, bind_info
->dev_info
, DEV_NAME_LEN
);
388 driver
->use_count
= 0;
389 driver
->next
= root_driver
;
390 driver
->attach
= NULL
; driver
->detach
= NULL
;
391 root_driver
= driver
;
394 for (b
= s
->bind
; b
; b
= b
->next
)
395 if ((driver
== b
->driver
) &&
396 (bind_info
->function
== b
->function
))
399 bind_info
->instance
= b
->instance
;
404 bind_req
.Function
= bind_info
->function
;
405 bind_req
.dev_info
= &driver
->dev_info
;
406 ret
= pcmcia_bind_device(&bind_req
);
407 if (ret
!= CS_SUCCESS
) {
408 cs_error(NULL
, BindDevice
, ret
);
409 printk(KERN_NOTICE
"ds: unable to bind '%s' to socket %d\n",
410 (char *)dev_info
, i
);
414 /* Add binding to list for this socket */
416 b
= kmalloc(sizeof(socket_bind_t
), GFP_KERNEL
);
418 b
->function
= bind_info
->function
;
423 if (driver
->attach
) {
424 b
->instance
= driver
->attach();
425 if (b
->instance
== NULL
) {
426 printk(KERN_NOTICE
"ds: unable to create instance "
427 "of '%s'!\n", (char *)bind_info
->dev_info
);
435 /*====================================================================*/
437 static int get_device_info(int i
, bind_info_t
*bind_info
, int first
)
439 socket_info_t
*s
= &socket_table
[i
];
443 #ifdef CONFIG_CARDBUS
445 * Some unbelievably ugly code to associate the PCI cardbus
446 * device and its driver with the PCMCIA "bind" information.
451 bus
= pcmcia_lookup_bus(s
->handle
);
453 struct list_head
*list
;
454 struct pci_dev
*dev
= NULL
;
456 list
= bus
->devices
.next
;
457 while (list
!= &bus
->devices
) {
458 struct pci_dev
*pdev
= pci_dev_b(list
);
466 /* Try to handle "next" here some way? */
468 if (dev
&& dev
->driver
) {
469 strncpy(bind_info
->name
, dev
->driver
->name
, DEV_NAME_LEN
);
470 bind_info
->name
[DEV_NAME_LEN
-1] = '\0';
471 bind_info
->major
= 0;
472 bind_info
->minor
= 0;
473 bind_info
->next
= NULL
;
480 for (b
= s
->bind
; b
; b
= b
->next
)
481 if ((strcmp((char *)b
->driver
->dev_info
,
482 (char *)bind_info
->dev_info
) == 0) &&
483 (b
->function
== bind_info
->function
))
485 if (b
== NULL
) return -ENODEV
;
486 if ((b
->instance
== NULL
) ||
487 (b
->instance
->state
& DEV_CONFIG_PENDING
))
490 node
= b
->instance
->dev
;
492 for (node
= b
->instance
->dev
; node
; node
= node
->next
)
493 if (node
== bind_info
->next
) break;
494 if (node
== NULL
) return -ENODEV
;
496 strncpy(bind_info
->name
, node
->dev_name
, DEV_NAME_LEN
);
497 bind_info
->name
[DEV_NAME_LEN
-1] = '\0';
498 bind_info
->major
= node
->major
;
499 bind_info
->minor
= node
->minor
;
500 bind_info
->next
= node
->next
;
503 } /* get_device_info */
505 /*====================================================================*/
507 static int unbind_request(int i
, bind_info_t
*bind_info
)
509 socket_info_t
*s
= &socket_table
[i
];
510 socket_bind_t
**b
, *c
;
512 DEBUG(2, "unbind_request(%d, '%s')\n", i
,
513 (char *)bind_info
->dev_info
);
514 for (b
= &s
->bind
; *b
; b
= &(*b
)->next
)
515 if ((strcmp((char *)(*b
)->driver
->dev_info
,
516 (char *)bind_info
->dev_info
) == 0) &&
517 ((*b
)->function
== bind_info
->function
))
523 c
->driver
->use_count
--;
524 if (c
->driver
->detach
) {
526 c
->driver
->detach(c
->instance
);
528 if (c
->driver
->use_count
== 0) {
530 for (d
= &root_driver
; *d
; d
= &((*d
)->next
))
531 if (c
->driver
== *d
) break;
540 } /* unbind_request */
542 /*======================================================================
544 The user-mode PC Card device interface
546 ======================================================================*/
548 static int ds_open(struct inode
*inode
, struct file
*file
)
550 socket_t i
= MINOR(inode
->i_rdev
);
554 DEBUG(0, "ds_open(socket %d)\n", i
);
555 if ((i
>= sockets
) || (sockets
== 0))
557 s
= &socket_table
[i
];
558 if ((file
->f_flags
& O_ACCMODE
) != O_RDONLY
) {
559 if (s
->state
& SOCKET_BUSY
)
562 s
->state
|= SOCKET_BUSY
;
565 user
= kmalloc(sizeof(user_info_t
), GFP_KERNEL
);
566 if (!user
) return -ENOMEM
;
567 user
->event_tail
= user
->event_head
= 0;
568 user
->next
= s
->user
;
569 user
->user_magic
= USER_MAGIC
;
571 file
->private_data
= user
;
573 if (s
->state
& SOCKET_PRESENT
)
574 queue_event(user
, CS_EVENT_CARD_INSERTION
);
578 /*====================================================================*/
580 static int ds_release(struct inode
*inode
, struct file
*file
)
582 socket_t i
= MINOR(inode
->i_rdev
);
584 user_info_t
*user
, **link
;
586 DEBUG(0, "ds_release(socket %d)\n", i
);
587 if ((i
>= sockets
) || (sockets
== 0))
590 s
= &socket_table
[i
];
591 user
= file
->private_data
;
592 if (CHECK_USER(user
))
595 /* Unlink user data structure */
596 if ((file
->f_flags
& O_ACCMODE
) != O_RDONLY
)
597 s
->state
&= ~SOCKET_BUSY
;
598 file
->private_data
= NULL
;
599 for (link
= &s
->user
; *link
; link
= &(*link
)->next
)
600 if (*link
== user
) break;
604 user
->user_magic
= 0;
611 /*====================================================================*/
613 static ssize_t
ds_read(struct file
*file
, char *buf
,
614 size_t count
, loff_t
*ppos
)
616 socket_t i
= MINOR(file
->f_dentry
->d_inode
->i_rdev
);
620 DEBUG(2, "ds_read(socket %d)\n", i
);
622 if ((i
>= sockets
) || (sockets
== 0))
626 s
= &socket_table
[i
];
627 user
= file
->private_data
;
628 if (CHECK_USER(user
))
631 if (queue_empty(user
)) {
632 interruptible_sleep_on(&s
->queue
);
633 if (signal_pending(current
))
636 put_user(get_queued_event(user
), (int *)buf
);
640 /*====================================================================*/
642 static ssize_t
ds_write(struct file
*file
, const char *buf
,
643 size_t count
, loff_t
*ppos
)
645 socket_t i
= MINOR(file
->f_dentry
->d_inode
->i_rdev
);
649 DEBUG(2, "ds_write(socket %d)\n", i
);
651 if ((i
>= sockets
) || (sockets
== 0))
655 if ((file
->f_flags
& O_ACCMODE
) == O_RDONLY
)
657 s
= &socket_table
[i
];
658 user
= file
->private_data
;
659 if (CHECK_USER(user
))
662 if (s
->req_pending
) {
664 get_user(s
->req_result
, (int *)buf
);
665 if ((s
->req_result
!= 0) || (s
->req_pending
== 0))
666 wake_up_interruptible(&s
->request
);
673 /*====================================================================*/
675 /* No kernel lock - fine */
676 static u_int
ds_poll(struct file
*file
, poll_table
*wait
)
678 socket_t i
= MINOR(file
->f_dentry
->d_inode
->i_rdev
);
682 DEBUG(2, "ds_poll(socket %d)\n", i
);
684 if ((i
>= sockets
) || (sockets
== 0))
686 s
= &socket_table
[i
];
687 user
= file
->private_data
;
688 if (CHECK_USER(user
))
690 poll_wait(file
, &s
->queue
, wait
);
691 if (!queue_empty(user
))
692 return POLLIN
| POLLRDNORM
;
696 /*====================================================================*/
698 static int ds_ioctl(struct inode
* inode
, struct file
* file
,
699 u_int cmd
, u_long arg
)
701 socket_t i
= MINOR(inode
->i_rdev
);
707 DEBUG(2, "ds_ioctl(socket %d, %#x, %#lx)\n", i
, cmd
, arg
);
709 if ((i
>= sockets
) || (sockets
== 0))
711 s
= &socket_table
[i
];
713 size
= (cmd
& IOCSIZE_MASK
) >> IOCSIZE_SHIFT
;
714 if (size
> sizeof(ds_ioctl_arg_t
)) return -EINVAL
;
716 /* Permission check */
717 if (!(cmd
& IOC_OUT
) && !capable(CAP_SYS_ADMIN
))
721 err
= verify_area(VERIFY_READ
, (char *)arg
, size
);
723 DEBUG(3, "ds_ioctl(): verify_read = %d\n", err
);
728 err
= verify_area(VERIFY_WRITE
, (char *)arg
, size
);
730 DEBUG(3, "ds_ioctl(): verify_write = %d\n", err
);
737 if (cmd
& IOC_IN
) copy_from_user((char *)&buf
, (char *)arg
, size
);
740 case DS_ADJUST_RESOURCE_INFO
:
741 ret
= pcmcia_adjust_resource_info(s
->handle
, &buf
.adjust
);
743 case DS_GET_CARD_SERVICES_INFO
:
744 ret
= pcmcia_get_card_services_info(&buf
.servinfo
);
746 case DS_GET_CONFIGURATION_INFO
:
747 ret
= pcmcia_get_configuration_info(s
->handle
, &buf
.config
);
749 case DS_GET_FIRST_TUPLE
:
750 ret
= pcmcia_get_first_tuple(s
->handle
, &buf
.tuple
);
752 case DS_GET_NEXT_TUPLE
:
753 ret
= pcmcia_get_next_tuple(s
->handle
, &buf
.tuple
);
755 case DS_GET_TUPLE_DATA
:
756 buf
.tuple
.TupleData
= buf
.tuple_parse
.data
;
757 buf
.tuple
.TupleDataMax
= sizeof(buf
.tuple_parse
.data
);
758 ret
= pcmcia_get_tuple_data(s
->handle
, &buf
.tuple
);
761 buf
.tuple
.TupleData
= buf
.tuple_parse
.data
;
762 ret
= pcmcia_parse_tuple(s
->handle
, &buf
.tuple
, &buf
.tuple_parse
.parse
);
765 ret
= pcmcia_reset_card(s
->handle
, NULL
);
768 ret
= pcmcia_get_status(s
->handle
, &buf
.status
);
770 case DS_VALIDATE_CIS
:
771 ret
= pcmcia_validate_cis(s
->handle
, &buf
.cisinfo
);
773 case DS_SUSPEND_CARD
:
774 ret
= pcmcia_suspend_card(s
->handle
, NULL
);
777 ret
= pcmcia_resume_card(s
->handle
, NULL
);
780 ret
= pcmcia_eject_card(s
->handle
, NULL
);
783 ret
= pcmcia_insert_card(s
->handle
, NULL
);
785 case DS_ACCESS_CONFIGURATION_REGISTER
:
786 if ((buf
.conf_reg
.Action
== CS_WRITE
) && !capable(CAP_SYS_ADMIN
))
788 ret
= pcmcia_access_configuration_register(s
->handle
, &buf
.conf_reg
);
790 case DS_GET_FIRST_REGION
:
791 ret
= pcmcia_get_first_region(s
->handle
, &buf
.region
);
793 case DS_GET_NEXT_REGION
:
794 ret
= pcmcia_get_next_region(s
->handle
, &buf
.region
);
796 case DS_GET_FIRST_WINDOW
:
797 buf
.win_info
.handle
= (window_handle_t
)s
->handle
;
798 ret
= pcmcia_get_first_window(&buf
.win_info
.handle
, &buf
.win_info
.window
);
800 case DS_GET_NEXT_WINDOW
:
801 ret
= pcmcia_get_next_window(&buf
.win_info
.handle
, &buf
.win_info
.window
);
803 case DS_GET_MEM_PAGE
:
804 ret
= pcmcia_get_mem_page(buf
.win_info
.handle
,
808 ret
= pcmcia_replace_cis(s
->handle
, &buf
.cisdump
);
810 case DS_BIND_REQUEST
:
811 if (!capable(CAP_SYS_ADMIN
)) return -EPERM
;
812 err
= bind_request(i
, &buf
.bind_info
);
814 case DS_GET_DEVICE_INFO
:
815 err
= get_device_info(i
, &buf
.bind_info
, 1);
817 case DS_GET_NEXT_DEVICE
:
818 err
= get_device_info(i
, &buf
.bind_info
, 0);
820 case DS_UNBIND_REQUEST
:
821 err
= unbind_request(i
, &buf
.bind_info
);
824 if (!suser()) return -EPERM
;
825 err
= bind_mtd(i
, &buf
.mtd_info
);
831 if ((err
== 0) && (ret
!= CS_SUCCESS
)) {
832 DEBUG(2, "ds_ioctl: ret = %d\n", ret
);
834 case CS_BAD_SOCKET
: case CS_NO_CARD
:
835 err
= -ENODEV
; break;
836 case CS_BAD_ARGS
: case CS_BAD_ATTRIBUTE
: case CS_BAD_IRQ
:
838 err
= -EINVAL
; break;
841 case CS_OUT_OF_RESOURCE
:
842 err
= -ENOSPC
; break;
843 case CS_NO_MORE_ITEMS
:
844 err
= -ENODATA
; break;
845 case CS_UNSUPPORTED_FUNCTION
:
846 err
= -ENOSYS
; break;
852 if (cmd
& IOC_OUT
) copy_to_user((char *)arg
, (char *)&buf
, size
);
857 /*====================================================================*/
859 static struct file_operations ds_fops
= {
869 EXPORT_SYMBOL(register_pccard_driver
);
870 EXPORT_SYMBOL(unregister_pccard_driver
);
872 /*====================================================================*/
874 int __init
init_pcmcia_ds(void)
876 client_reg_t client_reg
;
882 DEBUG(0, "%s\n", version
);
885 * Ugly. But we want to wait for the socket threads to have started up.
886 * We really should let the drivers themselves drive some of this..
888 current
->state
= TASK_INTERRUPTIBLE
;
889 schedule_timeout(HZ
/10);
891 pcmcia_get_card_services_info(&serv
);
892 if (serv
.Revision
!= CS_RELEASE_CODE
) {
893 printk(KERN_NOTICE
"ds: Card Services release does not match!\n");
896 if (serv
.Count
== 0) {
897 printk(KERN_NOTICE
"ds: no socket drivers loaded!\n");
901 sockets
= serv
.Count
;
902 socket_table
= kmalloc(sockets
*sizeof(socket_info_t
), GFP_KERNEL
);
903 if (!socket_table
) return -1;
904 for (i
= 0, s
= socket_table
; i
< sockets
; i
++, s
++) {
908 init_waitqueue_head(&s
->queue
);
909 init_waitqueue_head(&s
->request
);
911 init_timer(&s
->removal
);
913 s
->removal
.function
= &handle_removal
;
917 /* Set up hotline to Card Services */
918 client_reg
.dev_info
= bind
.dev_info
= &dev_info
;
919 client_reg
.Attributes
= INFO_MASTER_CLIENT
;
920 client_reg
.EventMask
=
921 CS_EVENT_CARD_INSERTION
| CS_EVENT_CARD_REMOVAL
|
922 CS_EVENT_RESET_PHYSICAL
| CS_EVENT_CARD_RESET
|
923 CS_EVENT_EJECTION_REQUEST
| CS_EVENT_INSERTION_REQUEST
|
924 CS_EVENT_PM_SUSPEND
| CS_EVENT_PM_RESUME
;
925 client_reg
.event_handler
= &ds_event
;
926 client_reg
.Version
= 0x0210;
927 for (i
= 0; i
< sockets
; i
++) {
929 bind
.Function
= BIND_FN_ALL
;
930 ret
= pcmcia_bind_device(&bind
);
931 if (ret
!= CS_SUCCESS
) {
932 cs_error(NULL
, BindDevice
, ret
);
935 client_reg
.event_callback_args
.client_data
= &socket_table
[i
];
936 ret
= pcmcia_register_client(&socket_table
[i
].handle
,
938 if (ret
!= CS_SUCCESS
) {
939 cs_error(NULL
, RegisterClient
, ret
);
944 /* Set up character device for user mode clients */
945 i
= register_chrdev(0, "pcmcia", &ds_fops
);
947 printk(KERN_NOTICE
"unable to find a free device # for "
948 "Driver Services\n");
952 #ifdef CONFIG_PROC_FS
954 create_proc_read_entry("drivers",0,proc_pccard
,proc_read_drivers
,NULL
);
962 int __init
init_module(void)
964 return init_pcmcia_ds();
967 void __exit
cleanup_module(void)
970 #ifdef CONFIG_PROC_FS
972 remove_proc_entry("drivers", proc_pccard
);
975 unregister_chrdev(major_dev
, "pcmcia");
976 for (i
= 0; i
< sockets
; i
++)
977 pcmcia_deregister_client(socket_table
[i
].handle
);