1 /*======================================================================
3 PC Card Driver Services
5 ds.c 1.112 2001/10/13 00:08:28
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 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.
32 ======================================================================*/
34 #include <linux/config.h>
35 #include <linux/module.h>
36 #include <linux/moduleparam.h>
37 #include <linux/init.h>
38 #include <linux/kernel.h>
39 #include <linux/major.h>
40 #include <linux/string.h>
41 #include <linux/errno.h>
42 #include <linux/slab.h>
44 #include <linux/fcntl.h>
45 #include <linux/sched.h>
46 #include <linux/smp_lock.h>
47 #include <linux/timer.h>
48 #include <linux/ioctl.h>
49 #include <linux/proc_fs.h>
50 #include <linux/poll.h>
51 #include <linux/pci.h>
52 #include <linux/list.h>
53 #include <linux/workqueue.h>
55 #include <asm/atomic.h>
57 #define IN_CARD_SERVICES
58 #include <pcmcia/version.h>
59 #include <pcmcia/cs_types.h>
60 #include <pcmcia/cs.h>
61 #include <pcmcia/bulkmem.h>
62 #include <pcmcia/cistpl.h>
63 #include <pcmcia/ds.h>
64 #include <pcmcia/ss.h>
66 #include "cs_internal.h"
68 /*====================================================================*/
70 /* Module parameters */
72 MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
73 MODULE_DESCRIPTION("PCMCIA Driver Services");
74 MODULE_LICENSE("Dual MPL/GPL");
79 module_param(pc_debug, int, 0644);
81 #define ds_dbg(lvl, fmt, arg...) do { \
82 if (pc_debug > (lvl)) \
83 printk(KERN_DEBUG "ds: " fmt , ## arg); \
86 #define ds_dbg(lvl, fmt, arg...) do { } while (0)
89 /*====================================================================*/
91 typedef struct socket_bind_t {
92 struct pcmcia_driver *driver;
95 struct socket_bind_t *next;
98 /* Device user information */
100 #define USER_MAGIC 0x7ea4
101 #define CHECK_USER(u) \
102 (((u) == NULL) || ((u)->user_magic != USER_MAGIC))
103 typedef struct user_info_t {
105 int event_head, event_tail;
106 event_t event[MAX_EVENTS];
107 struct user_info_t *next;
108 struct pcmcia_bus_socket *socket;
111 /* Socket state information */
112 struct pcmcia_bus_socket {
114 client_handle_t handle;
117 int req_pending, req_result;
118 wait_queue_head_t queue, request;
119 struct work_struct removal;
121 struct pcmcia_socket *parent;
124 #define DS_SOCKET_PRESENT 0x01
125 #define DS_SOCKET_BUSY 0x02
126 #define DS_SOCKET_REMOVAL_PENDING 0x10
127 #define DS_SOCKET_DEAD 0x80
129 /*====================================================================*/
131 /* Device driver ID passed to Card Services */
132 static dev_info_t dev_info = "Driver Services";
134 static int major_dev = -1;
136 extern struct proc_dir_entry *proc_pccard;
138 /*====================================================================*/
140 /* code which was in cs.c before */
142 /*======================================================================
144 Bind_device() associates a device driver with a particular socket.
145 It is normally called by Driver Services after it has identified
146 a newly inserted card. An instance of that driver will then be
147 eligible to register as a client of this socket.
149 ======================================================================*/
151 static int pcmcia_bind_device(bind_req_t *req)
154 struct pcmcia_socket *s;
158 return CS_BAD_SOCKET;
160 client = (client_t *) kmalloc(sizeof(client_t), GFP_KERNEL);
162 return CS_OUT_OF_RESOURCE;
163 memset(client, '\0', sizeof(client_t));
164 client->client_magic = CLIENT_MAGIC;
165 strlcpy(client->dev_info, (char *)req->dev_info, DEV_NAME_LEN);
167 client->Function = req->Function;
168 client->state = CLIENT_UNBOUND;
169 client->erase_busy.next = &client->erase_busy;
170 client->erase_busy.prev = &client->erase_busy;
171 init_waitqueue_head(&client->mtd_req);
172 client->next = s->clients;
174 ds_dbg(1, "%s: bind_device(): client 0x%p, dev %s\n",
175 cs_socket_name(client->Socket), client, client->dev_info);
180 /*======================================================================
182 Bind_mtd() associates a device driver with a particular memory
183 region. It is normally called by Driver Services after it has
184 identified a memory device type. An instance of the corresponding
185 driver will then be able to register to control this region.
187 ======================================================================*/
189 static int pcmcia_bind_mtd(mtd_bind_t *req)
191 struct pcmcia_socket *s;
192 memory_handle_t region;
196 return CS_BAD_SOCKET;
198 if (req->Attributes & REGION_TYPE_AM)
199 region = s->a_region;
201 region = s->c_region;
204 if (region->info.CardOffset == req->CardOffset)
206 region = region->info.next;
208 if (!region || (region->mtd != NULL))
209 return CS_BAD_OFFSET;
210 strlcpy(region->dev_info, (char *)req->dev_info, DEV_NAME_LEN);
212 ds_dbg(1, "%s: bind_mtd: attr 0x%x, offset 0x%x, dev %s\n",
213 cs_socket_name(s), req->Attributes, req->CardOffset,
214 (char *)req->dev_info);
219 /* String tables for error messages */
221 typedef struct lookup_t {
226 static const lookup_t error_table[] = {
227 { CS_SUCCESS, "Operation succeeded" },
228 { CS_BAD_ADAPTER, "Bad adapter" },
229 { CS_BAD_ATTRIBUTE, "Bad attribute", },
230 { CS_BAD_BASE, "Bad base address" },
231 { CS_BAD_EDC, "Bad EDC" },
232 { CS_BAD_IRQ, "Bad IRQ" },
233 { CS_BAD_OFFSET, "Bad offset" },
234 { CS_BAD_PAGE, "Bad page number" },
235 { CS_READ_FAILURE, "Read failure" },
236 { CS_BAD_SIZE, "Bad size" },
237 { CS_BAD_SOCKET, "Bad socket" },
238 { CS_BAD_TYPE, "Bad type" },
239 { CS_BAD_VCC, "Bad Vcc" },
240 { CS_BAD_VPP, "Bad Vpp" },
241 { CS_BAD_WINDOW, "Bad window" },
242 { CS_WRITE_FAILURE, "Write failure" },
243 { CS_NO_CARD, "No card present" },
244 { CS_UNSUPPORTED_FUNCTION, "Usupported function" },
245 { CS_UNSUPPORTED_MODE, "Unsupported mode" },
246 { CS_BAD_SPEED, "Bad speed" },
247 { CS_BUSY, "Resource busy" },
248 { CS_GENERAL_FAILURE, "General failure" },
249 { CS_WRITE_PROTECTED, "Write protected" },
250 { CS_BAD_ARG_LENGTH, "Bad argument length" },
251 { CS_BAD_ARGS, "Bad arguments" },
252 { CS_CONFIGURATION_LOCKED, "Configuration locked" },
253 { CS_IN_USE, "Resource in use" },
254 { CS_NO_MORE_ITEMS, "No more items" },
255 { CS_OUT_OF_RESOURCE, "Out of resource" },
256 { CS_BAD_HANDLE, "Bad handle" },
257 { CS_BAD_TUPLE, "Bad CIS tuple" }
261 static const lookup_t service_table[] = {
262 { AccessConfigurationRegister, "AccessConfigurationRegister" },
263 { AddSocketServices, "AddSocketServices" },
264 { AdjustResourceInfo, "AdjustResourceInfo" },
265 { CheckEraseQueue, "CheckEraseQueue" },
266 { CloseMemory, "CloseMemory" },
267 { DeregisterClient, "DeregisterClient" },
268 { DeregisterEraseQueue, "DeregisterEraseQueue" },
269 { GetCardServicesInfo, "GetCardServicesInfo" },
270 { GetClientInfo, "GetClientInfo" },
271 { GetConfigurationInfo, "GetConfigurationInfo" },
272 { GetEventMask, "GetEventMask" },
273 { GetFirstClient, "GetFirstClient" },
274 { GetFirstRegion, "GetFirstRegion" },
275 { GetFirstTuple, "GetFirstTuple" },
276 { GetNextClient, "GetNextClient" },
277 { GetNextRegion, "GetNextRegion" },
278 { GetNextTuple, "GetNextTuple" },
279 { GetStatus, "GetStatus" },
280 { GetTupleData, "GetTupleData" },
281 { MapMemPage, "MapMemPage" },
282 { ModifyConfiguration, "ModifyConfiguration" },
283 { ModifyWindow, "ModifyWindow" },
284 { OpenMemory, "OpenMemory" },
285 { ParseTuple, "ParseTuple" },
286 { ReadMemory, "ReadMemory" },
287 { RegisterClient, "RegisterClient" },
288 { RegisterEraseQueue, "RegisterEraseQueue" },
289 { RegisterMTD, "RegisterMTD" },
290 { ReleaseConfiguration, "ReleaseConfiguration" },
291 { ReleaseIO, "ReleaseIO" },
292 { ReleaseIRQ, "ReleaseIRQ" },
293 { ReleaseWindow, "ReleaseWindow" },
294 { RequestConfiguration, "RequestConfiguration" },
295 { RequestIO, "RequestIO" },
296 { RequestIRQ, "RequestIRQ" },
297 { RequestSocketMask, "RequestSocketMask" },
298 { RequestWindow, "RequestWindow" },
299 { ResetCard, "ResetCard" },
300 { SetEventMask, "SetEventMask" },
301 { ValidateCIS, "ValidateCIS" },
302 { WriteMemory, "WriteMemory" },
303 { BindDevice, "BindDevice" },
304 { BindMTD, "BindMTD" },
305 { ReportError, "ReportError" },
306 { SuspendCard, "SuspendCard" },
307 { ResumeCard, "ResumeCard" },
308 { EjectCard, "EjectCard" },
309 { InsertCard, "InsertCard" },
310 { ReplaceCIS, "ReplaceCIS" }
314 int pcmcia_report_error(client_handle_t handle, error_info_t *err)
319 if (CHECK_HANDLE(handle))
322 printk(KERN_NOTICE "%s: ", handle->dev_info);
324 for (i = 0; i < ARRAY_SIZE(service_table); i++)
325 if (service_table[i].key == err->func)
327 if (i < ARRAY_SIZE(service_table))
328 serv = service_table[i].msg;
330 serv = "Unknown service number";
332 for (i = 0; i < ARRAY_SIZE(error_table); i++)
333 if (error_table[i].key == err->retcode)
335 if (i < ARRAY_SIZE(error_table))
336 printk("%s: %s\n", serv, error_table[i].msg);
338 printk("%s: Unknown error code %#x\n", serv, err->retcode);
342 EXPORT_SYMBOL(pcmcia_report_error);
344 /* end of code which was in cs.c before */
346 /*======================================================================*/
348 void cs_error(client_handle_t handle, int func, int ret)
350 error_info_t err = { func, ret };
351 pcmcia_report_error(handle, &err);
353 EXPORT_SYMBOL(cs_error);
355 /*======================================================================*/
357 static struct pcmcia_driver * get_pcmcia_driver (dev_info_t *dev_info);
358 static struct pcmcia_bus_socket * get_socket_info_by_nr(unsigned int nr);
360 static void pcmcia_put_bus_socket(struct pcmcia_bus_socket *s)
362 if (atomic_dec_and_test(&s->refcount))
366 static struct pcmcia_bus_socket *pcmcia_get_bus_socket(int nr)
368 struct pcmcia_bus_socket *s;
370 s = get_socket_info_by_nr(nr);
372 WARN_ON(atomic_read(&s->refcount) == 0);
373 atomic_inc(&s->refcount);
379 * pcmcia_register_driver - register a PCMCIA driver with the bus core
381 * Registers a PCMCIA driver with the PCMCIA bus core.
383 int pcmcia_register_driver(struct pcmcia_driver *driver)
388 driver->use_count = 0;
389 driver->drv.bus = &pcmcia_bus_type;
391 return driver_register(&driver->drv);
393 EXPORT_SYMBOL(pcmcia_register_driver);
396 * pcmcia_unregister_driver - unregister a PCMCIA driver with the bus core
398 void pcmcia_unregister_driver(struct pcmcia_driver *driver)
400 driver_unregister(&driver->drv);
402 EXPORT_SYMBOL(pcmcia_unregister_driver);
404 #ifdef CONFIG_PROC_FS
405 static struct proc_dir_entry *proc_pccard = NULL;
407 static int proc_read_drivers_callback(struct device_driver *driver, void *d)
410 struct pcmcia_driver *p_dev = container_of(driver,
411 struct pcmcia_driver, drv);
413 *p += sprintf(*p, "%-24.24s 1 %d\n", driver->name, p_dev->use_count);
419 static int proc_read_drivers(char *buf, char **start, off_t pos,
420 int count, int *eof, void *data)
424 bus_for_each_drv(&pcmcia_bus_type, NULL,
425 (void *) &p, proc_read_drivers_callback);
431 /*======================================================================
433 These manage a ring buffer of events pending for one user process
435 ======================================================================*/
437 static int queue_empty(user_info_t *user)
439 return (user->event_head == user->event_tail);
442 static event_t get_queued_event(user_info_t *user)
444 user->event_tail = (user->event_tail+1) % MAX_EVENTS;
445 return user->event[user->event_tail];
448 static void queue_event(user_info_t *user, event_t event)
450 user->event_head = (user->event_head+1) % MAX_EVENTS;
451 if (user->event_head == user->event_tail)
452 user->event_tail = (user->event_tail+1) % MAX_EVENTS;
453 user->event[user->event_head] = event;
456 static void handle_event(struct pcmcia_bus_socket *s, event_t event)
459 for (user = s->user; user; user = user->next)
460 queue_event(user, event);
461 wake_up_interruptible(&s->queue);
464 static int handle_request(struct pcmcia_bus_socket *s, event_t event)
466 if (s->req_pending != 0)
468 if (s->state & DS_SOCKET_BUSY)
470 handle_event(s, event);
471 if (wait_event_interruptible(s->request, s->req_pending <= 0))
473 if (s->state & DS_SOCKET_BUSY)
474 return s->req_result;
478 static void handle_removal(void *data)
480 struct pcmcia_bus_socket *s = data;
481 handle_event(s, CS_EVENT_CARD_REMOVAL);
482 s->state &= ~DS_SOCKET_REMOVAL_PENDING;
485 /*======================================================================
487 The card status event handler.
489 ======================================================================*/
491 static int ds_event(event_t event, int priority,
492 event_callback_args_t *args)
494 struct pcmcia_bus_socket *s;
496 ds_dbg(1, "ds_event(0x%06x, %d, 0x%p)\n",
497 event, priority, args->client_handle);
498 s = args->client_data;
502 case CS_EVENT_CARD_REMOVAL:
503 s->state &= ~DS_SOCKET_PRESENT;
504 if (!(s->state & DS_SOCKET_REMOVAL_PENDING)) {
505 s->state |= DS_SOCKET_REMOVAL_PENDING;
506 schedule_delayed_work(&s->removal, HZ/10);
510 case CS_EVENT_CARD_INSERTION:
511 s->state |= DS_SOCKET_PRESENT;
512 handle_event(s, event);
515 case CS_EVENT_EJECTION_REQUEST:
516 return handle_request(s, event);
520 handle_event(s, event);
527 /*======================================================================
529 bind_mtd() connects a memory region with an MTD client.
531 ======================================================================*/
533 static int bind_mtd(struct pcmcia_bus_socket *bus_sock, mtd_info_t *mtd_info)
538 bind_req.dev_info = &mtd_info->dev_info;
539 bind_req.Attributes = mtd_info->Attributes;
540 bind_req.Socket = bus_sock->parent;
541 bind_req.CardOffset = mtd_info->CardOffset;
542 ret = pcmcia_bind_mtd(&bind_req);
543 if (ret != CS_SUCCESS) {
544 cs_error(NULL, BindMTD, ret);
545 printk(KERN_NOTICE "ds: unable to bind MTD '%s' to socket %d"
547 (char *)bind_req.dev_info, bus_sock->parent->sock, bind_req.CardOffset);
553 /*======================================================================
555 bind_request() connects a socket to a particular client driver.
556 It looks up the specified device ID in the list of registered
557 drivers, binds it to the socket, and tries to create an instance
558 of the device. unbind_request() deletes a driver instance.
560 ======================================================================*/
562 static int bind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info)
564 struct pcmcia_driver *driver;
572 ds_dbg(2, "bind_request(%d, '%s')\n", s->parent->sock,
573 (char *)bind_info->dev_info);
574 driver = get_pcmcia_driver(&bind_info->dev_info);
578 for (b = s->bind; b; b = b->next)
579 if ((driver == b->driver) &&
580 (bind_info->function == b->function))
583 bind_info->instance = b->instance;
587 if (!try_module_get(driver->owner))
590 bind_req.Socket = s->parent;
591 bind_req.Function = bind_info->function;
592 bind_req.dev_info = (dev_info_t *) driver->drv.name;
593 ret = pcmcia_bind_device(&bind_req);
594 if (ret != CS_SUCCESS) {
595 cs_error(NULL, BindDevice, ret);
596 printk(KERN_NOTICE "ds: unable to bind '%s' to socket %d\n",
597 (char *)dev_info, s->parent->sock);
598 module_put(driver->owner);
602 /* Add binding to list for this socket */
604 b = kmalloc(sizeof(socket_bind_t), GFP_KERNEL);
608 module_put(driver->owner);
612 b->function = bind_info->function;
617 if (driver->attach) {
618 b->instance = driver->attach();
619 if (b->instance == NULL) {
620 printk(KERN_NOTICE "ds: unable to create instance "
621 "of '%s'!\n", (char *)bind_info->dev_info);
622 module_put(driver->owner);
630 /*====================================================================*/
632 static int get_device_info(struct pcmcia_bus_socket *s, bind_info_t *bind_info, int first)
637 #ifdef CONFIG_CARDBUS
639 * Some unbelievably ugly code to associate the PCI cardbus
640 * device and its driver with the PCMCIA "bind" information.
645 bus = pcmcia_lookup_bus(s->handle);
647 struct list_head *list;
648 struct pci_dev *dev = NULL;
650 list = bus->devices.next;
651 while (list != &bus->devices) {
652 struct pci_dev *pdev = pci_dev_b(list);
660 /* Try to handle "next" here some way? */
662 if (dev && dev->driver) {
663 strlcpy(bind_info->name, dev->driver->name, DEV_NAME_LEN);
664 bind_info->major = 0;
665 bind_info->minor = 0;
666 bind_info->next = NULL;
673 for (b = s->bind; b; b = b->next)
674 if ((strcmp((char *)b->driver->drv.name,
675 (char *)bind_info->dev_info) == 0) &&
676 (b->function == bind_info->function))
678 if (b == NULL) return -ENODEV;
679 if ((b->instance == NULL) ||
680 (b->instance->state & DEV_CONFIG_PENDING))
683 node = b->instance->dev;
685 for (node = b->instance->dev; node; node = node->next)
686 if (node == bind_info->next) break;
687 if (node == NULL) return -ENODEV;
689 strlcpy(bind_info->name, node->dev_name, DEV_NAME_LEN);
690 bind_info->major = node->major;
691 bind_info->minor = node->minor;
692 bind_info->next = node->next;
695 } /* get_device_info */
697 /*====================================================================*/
699 static int unbind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info)
701 socket_bind_t **b, *c;
703 ds_dbg(2, "unbind_request(%d, '%s')\n", s->parent->sock,
704 (char *)bind_info->dev_info);
705 for (b = &s->bind; *b; b = &(*b)->next)
706 if ((strcmp((char *)(*b)->driver->drv.name,
707 (char *)bind_info->dev_info) == 0) &&
708 ((*b)->function == bind_info->function))
714 c->driver->use_count--;
715 if (c->driver->detach) {
717 c->driver->detach(c->instance);
719 module_put(c->driver->owner);
723 } /* unbind_request */
725 /*======================================================================
727 The user-mode PC Card device interface
729 ======================================================================*/
731 static int ds_open(struct inode *inode, struct file *file)
733 socket_t i = iminor(inode);
734 struct pcmcia_bus_socket *s;
737 ds_dbg(0, "ds_open(socket %d)\n", i);
739 s = pcmcia_get_bus_socket(i);
743 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
744 if (s->state & DS_SOCKET_BUSY)
747 s->state |= DS_SOCKET_BUSY;
750 user = kmalloc(sizeof(user_info_t), GFP_KERNEL);
751 if (!user) return -ENOMEM;
752 user->event_tail = user->event_head = 0;
753 user->next = s->user;
754 user->user_magic = USER_MAGIC;
757 file->private_data = user;
759 if (s->state & DS_SOCKET_PRESENT)
760 queue_event(user, CS_EVENT_CARD_INSERTION);
764 /*====================================================================*/
766 static int ds_release(struct inode *inode, struct file *file)
768 struct pcmcia_bus_socket *s;
769 user_info_t *user, **link;
771 ds_dbg(0, "ds_release(socket %d)\n", iminor(inode));
773 user = file->private_data;
774 if (CHECK_USER(user))
779 /* Unlink user data structure */
780 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
781 s->state &= ~DS_SOCKET_BUSY;
783 wake_up_interruptible(&s->request);
785 file->private_data = NULL;
786 for (link = &s->user; *link; link = &(*link)->next)
787 if (*link == user) break;
791 user->user_magic = 0;
793 pcmcia_put_bus_socket(s);
798 /*====================================================================*/
800 static ssize_t ds_read(struct file *file, char __user *buf,
801 size_t count, loff_t *ppos)
803 struct pcmcia_bus_socket *s;
807 ds_dbg(2, "ds_read(socket %d)\n", iminor(file->f_dentry->d_inode));
812 user = file->private_data;
813 if (CHECK_USER(user))
817 if (s->state & DS_SOCKET_DEAD)
820 ret = wait_event_interruptible(s->queue, !queue_empty(user));
822 ret = put_user(get_queued_event(user), (int __user *)buf) ? -EFAULT : 4;
827 /*====================================================================*/
829 static ssize_t ds_write(struct file *file, const char __user *buf,
830 size_t count, loff_t *ppos)
832 struct pcmcia_bus_socket *s;
835 ds_dbg(2, "ds_write(socket %d)\n", iminor(file->f_dentry->d_inode));
839 if ((file->f_flags & O_ACCMODE) == O_RDONLY)
842 user = file->private_data;
843 if (CHECK_USER(user))
847 if (s->state & DS_SOCKET_DEAD)
850 if (s->req_pending) {
852 get_user(s->req_result, (int __user *)buf);
853 if ((s->req_result != 0) || (s->req_pending == 0))
854 wake_up_interruptible(&s->request);
861 /*====================================================================*/
863 /* No kernel lock - fine */
864 static u_int ds_poll(struct file *file, poll_table *wait)
866 struct pcmcia_bus_socket *s;
869 ds_dbg(2, "ds_poll(socket %d)\n", iminor(file->f_dentry->d_inode));
871 user = file->private_data;
872 if (CHECK_USER(user))
876 * We don't check for a dead socket here since that
877 * will send cardmgr into an endless spin.
879 poll_wait(file, &s->queue, wait);
880 if (!queue_empty(user))
881 return POLLIN | POLLRDNORM;
885 /*====================================================================*/
887 static int ds_ioctl(struct inode * inode, struct file * file,
888 u_int cmd, u_long arg)
890 struct pcmcia_bus_socket *s;
891 void __user *uarg = (char __user *)arg;
897 ds_dbg(2, "ds_ioctl(socket %d, %#x, %#lx)\n", iminor(inode), cmd, arg);
899 user = file->private_data;
900 if (CHECK_USER(user))
904 if (s->state & DS_SOCKET_DEAD)
907 size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
908 if (size > sizeof(ds_ioctl_arg_t)) return -EINVAL;
910 /* Permission check */
911 if (!(cmd & IOC_OUT) && !capable(CAP_SYS_ADMIN))
915 err = verify_area(VERIFY_READ, uarg, size);
917 ds_dbg(3, "ds_ioctl(): verify_read = %d\n", err);
922 err = verify_area(VERIFY_WRITE, uarg, size);
924 ds_dbg(3, "ds_ioctl(): verify_write = %d\n", err);
931 if (cmd & IOC_IN) __copy_from_user((char *)&buf, uarg, size);
934 case DS_ADJUST_RESOURCE_INFO:
935 ret = pcmcia_adjust_resource_info(s->handle, &buf.adjust);
937 case DS_GET_CARD_SERVICES_INFO:
938 ret = pcmcia_get_card_services_info(&buf.servinfo);
940 case DS_GET_CONFIGURATION_INFO:
941 ret = pcmcia_get_configuration_info(s->handle, &buf.config);
943 case DS_GET_FIRST_TUPLE:
944 ret = pcmcia_get_first_tuple(s->handle, &buf.tuple);
946 case DS_GET_NEXT_TUPLE:
947 ret = pcmcia_get_next_tuple(s->handle, &buf.tuple);
949 case DS_GET_TUPLE_DATA:
950 buf.tuple.TupleData = buf.tuple_parse.data;
951 buf.tuple.TupleDataMax = sizeof(buf.tuple_parse.data);
952 ret = pcmcia_get_tuple_data(s->handle, &buf.tuple);
955 buf.tuple.TupleData = buf.tuple_parse.data;
956 ret = pcmcia_parse_tuple(s->handle, &buf.tuple, &buf.tuple_parse.parse);
959 ret = pcmcia_reset_card(s->handle, NULL);
962 ret = pcmcia_get_status(s->handle, &buf.status);
964 case DS_VALIDATE_CIS:
965 ret = pcmcia_validate_cis(s->handle, &buf.cisinfo);
967 case DS_SUSPEND_CARD:
968 ret = pcmcia_suspend_card(s->parent);
971 ret = pcmcia_resume_card(s->parent);
974 ret = pcmcia_eject_card(s->parent);
977 ret = pcmcia_insert_card(s->parent);
979 case DS_ACCESS_CONFIGURATION_REGISTER:
980 if ((buf.conf_reg.Action == CS_WRITE) && !capable(CAP_SYS_ADMIN))
982 ret = pcmcia_access_configuration_register(s->handle, &buf.conf_reg);
984 case DS_GET_FIRST_REGION:
985 ret = pcmcia_get_first_region(s->handle, &buf.region);
987 case DS_GET_NEXT_REGION:
988 ret = pcmcia_get_next_region(s->handle, &buf.region);
990 case DS_GET_FIRST_WINDOW:
991 buf.win_info.handle = (window_handle_t)s->handle;
992 ret = pcmcia_get_first_window(&buf.win_info.handle, &buf.win_info.window);
994 case DS_GET_NEXT_WINDOW:
995 ret = pcmcia_get_next_window(&buf.win_info.handle, &buf.win_info.window);
997 case DS_GET_MEM_PAGE:
998 ret = pcmcia_get_mem_page(buf.win_info.handle,
1001 case DS_REPLACE_CIS:
1002 ret = pcmcia_replace_cis(s->handle, &buf.cisdump);
1004 case DS_BIND_REQUEST:
1005 if (!capable(CAP_SYS_ADMIN)) return -EPERM;
1006 err = bind_request(s, &buf.bind_info);
1008 case DS_GET_DEVICE_INFO:
1009 err = get_device_info(s, &buf.bind_info, 1);
1011 case DS_GET_NEXT_DEVICE:
1012 err = get_device_info(s, &buf.bind_info, 0);
1014 case DS_UNBIND_REQUEST:
1015 err = unbind_request(s, &buf.bind_info);
1018 if (!capable(CAP_SYS_ADMIN)) return -EPERM;
1019 err = bind_mtd(s, &buf.mtd_info);
1025 if ((err == 0) && (ret != CS_SUCCESS)) {
1026 ds_dbg(2, "ds_ioctl: ret = %d\n", ret);
1028 case CS_BAD_SOCKET: case CS_NO_CARD:
1029 err = -ENODEV; break;
1030 case CS_BAD_ARGS: case CS_BAD_ATTRIBUTE: case CS_BAD_IRQ:
1032 err = -EINVAL; break;
1034 err = -EBUSY; break;
1035 case CS_OUT_OF_RESOURCE:
1036 err = -ENOSPC; break;
1037 case CS_NO_MORE_ITEMS:
1038 err = -ENODATA; break;
1039 case CS_UNSUPPORTED_FUNCTION:
1040 err = -ENOSYS; break;
1046 if (cmd & IOC_OUT) __copy_to_user(uarg, (char *)&buf, size);
1051 /*====================================================================*/
1053 static struct file_operations ds_fops = {
1054 .owner = THIS_MODULE,
1056 .release = ds_release,
1063 static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev)
1065 struct pcmcia_socket *socket = class_dev->class_data;
1066 client_reg_t client_reg;
1068 struct pcmcia_bus_socket *s;
1071 s = kmalloc(sizeof(struct pcmcia_bus_socket), GFP_KERNEL);
1074 memset(s, 0, sizeof(struct pcmcia_bus_socket));
1075 atomic_set(&s->refcount, 1);
1078 * Ugly. But we want to wait for the socket threads to have started up.
1079 * We really should let the drivers themselves drive some of this..
1081 current->state = TASK_INTERRUPTIBLE;
1082 schedule_timeout(HZ/4);
1084 init_waitqueue_head(&s->queue);
1085 init_waitqueue_head(&s->request);
1087 /* initialize data */
1088 INIT_WORK(&s->removal, handle_removal, s);
1091 /* Set up hotline to Card Services */
1092 client_reg.dev_info = bind.dev_info = &dev_info;
1094 bind.Socket = socket;
1095 bind.Function = BIND_FN_ALL;
1096 ret = pcmcia_bind_device(&bind);
1097 if (ret != CS_SUCCESS) {
1098 cs_error(NULL, BindDevice, ret);
1103 client_reg.Attributes = INFO_MASTER_CLIENT;
1104 client_reg.EventMask =
1105 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
1106 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
1107 CS_EVENT_EJECTION_REQUEST | CS_EVENT_INSERTION_REQUEST |
1108 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
1109 client_reg.event_handler = &ds_event;
1110 client_reg.Version = 0x0210;
1111 client_reg.event_callback_args.client_data = s;
1112 ret = pcmcia_register_client(&s->handle, &client_reg);
1113 if (ret != CS_SUCCESS) {
1114 cs_error(NULL, RegisterClient, ret);
1125 static void pcmcia_bus_remove_socket(struct class_device *class_dev)
1127 struct pcmcia_socket *socket = class_dev->class_data;
1129 if (!socket || !socket->pcmcia)
1132 flush_scheduled_work();
1134 pcmcia_deregister_client(socket->pcmcia->handle);
1136 socket->pcmcia->state |= DS_SOCKET_DEAD;
1137 pcmcia_put_bus_socket(socket->pcmcia);
1138 socket->pcmcia = NULL;
1144 /* the pcmcia_bus_interface is used to handle pcmcia socket devices */
1145 static struct class_interface pcmcia_bus_interface = {
1146 .class = &pcmcia_socket_class,
1147 .add = &pcmcia_bus_add_socket,
1148 .remove = &pcmcia_bus_remove_socket,
1152 struct bus_type pcmcia_bus_type = {
1155 EXPORT_SYMBOL(pcmcia_bus_type);
1158 static int __init init_pcmcia_bus(void)
1162 bus_register(&pcmcia_bus_type);
1163 class_interface_register(&pcmcia_bus_interface);
1165 /* Set up character device for user mode clients */
1166 i = register_chrdev(0, "pcmcia", &ds_fops);
1168 printk(KERN_NOTICE "unable to find a free device # for "
1169 "Driver Services\n");
1173 #ifdef CONFIG_PROC_FS
1174 proc_pccard = proc_mkdir("pccard", proc_bus);
1176 create_proc_read_entry("drivers",0,proc_pccard,proc_read_drivers,NULL);
1181 fs_initcall(init_pcmcia_bus); /* one level after subsys_initcall so that
1182 * pcmcia_socket_class is already registered */
1185 static void __exit exit_pcmcia_bus(void)
1187 class_interface_unregister(&pcmcia_bus_interface);
1189 #ifdef CONFIG_PROC_FS
1191 remove_proc_entry("drivers", proc_pccard);
1192 remove_proc_entry("pccard", proc_bus);
1195 if (major_dev != -1)
1196 unregister_chrdev(major_dev, "pcmcia");
1198 bus_unregister(&pcmcia_bus_type);
1200 module_exit(exit_pcmcia_bus);
1204 /* helpers for backwards-compatible functions */
1206 static struct pcmcia_bus_socket * get_socket_info_by_nr(unsigned int nr)
1208 struct pcmcia_socket * s = pcmcia_get_socket_by_nr(nr);
1215 /* backwards-compatible accessing of driver --- by name! */
1219 struct pcmcia_driver *drv;
1222 static int cmp_drv_callback(struct device_driver *drv, void *data)
1224 struct cmp_data *cmp = data;
1225 if (strncmp((char *)cmp->dev_info, (char *)drv->name,
1226 DEV_NAME_LEN) == 0) {
1227 cmp->drv = container_of(drv, struct pcmcia_driver, drv);
1233 static struct pcmcia_driver * get_pcmcia_driver (dev_info_t *dev_info)
1236 struct cmp_data cmp = {
1237 .dev_info = dev_info,
1240 ret = bus_for_each_drv(&pcmcia_bus_type, NULL, &cmp, cmp_drv_callback);