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 *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 *)buf) ? -EFAULT : 4;
827 /*====================================================================*/
829 static ssize_t ds_write(struct file *file, const char *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 *)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;
896 ds_dbg(2, "ds_ioctl(socket %d, %#x, %#lx)\n", iminor(inode), cmd, arg);
898 user = file->private_data;
899 if (CHECK_USER(user))
903 if (s->state & DS_SOCKET_DEAD)
906 size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
907 if (size > sizeof(ds_ioctl_arg_t)) return -EINVAL;
909 /* Permission check */
910 if (!(cmd & IOC_OUT) && !capable(CAP_SYS_ADMIN))
914 err = verify_area(VERIFY_READ, (char *)arg, size);
916 ds_dbg(3, "ds_ioctl(): verify_read = %d\n", err);
921 err = verify_area(VERIFY_WRITE, (char *)arg, size);
923 ds_dbg(3, "ds_ioctl(): verify_write = %d\n", err);
930 if (cmd & IOC_IN) __copy_from_user((char *)&buf, (char *)arg, size);
933 case DS_ADJUST_RESOURCE_INFO:
934 ret = pcmcia_adjust_resource_info(s->handle, &buf.adjust);
936 case DS_GET_CARD_SERVICES_INFO:
937 ret = pcmcia_get_card_services_info(&buf.servinfo);
939 case DS_GET_CONFIGURATION_INFO:
940 ret = pcmcia_get_configuration_info(s->handle, &buf.config);
942 case DS_GET_FIRST_TUPLE:
943 ret = pcmcia_get_first_tuple(s->handle, &buf.tuple);
945 case DS_GET_NEXT_TUPLE:
946 ret = pcmcia_get_next_tuple(s->handle, &buf.tuple);
948 case DS_GET_TUPLE_DATA:
949 buf.tuple.TupleData = buf.tuple_parse.data;
950 buf.tuple.TupleDataMax = sizeof(buf.tuple_parse.data);
951 ret = pcmcia_get_tuple_data(s->handle, &buf.tuple);
954 buf.tuple.TupleData = buf.tuple_parse.data;
955 ret = pcmcia_parse_tuple(s->handle, &buf.tuple, &buf.tuple_parse.parse);
958 ret = pcmcia_reset_card(s->handle, NULL);
961 ret = pcmcia_get_status(s->handle, &buf.status);
963 case DS_VALIDATE_CIS:
964 ret = pcmcia_validate_cis(s->handle, &buf.cisinfo);
966 case DS_SUSPEND_CARD:
967 ret = pcmcia_suspend_card(s->parent);
970 ret = pcmcia_resume_card(s->parent);
973 ret = pcmcia_eject_card(s->parent);
976 ret = pcmcia_insert_card(s->parent);
978 case DS_ACCESS_CONFIGURATION_REGISTER:
979 if ((buf.conf_reg.Action == CS_WRITE) && !capable(CAP_SYS_ADMIN))
981 ret = pcmcia_access_configuration_register(s->handle, &buf.conf_reg);
983 case DS_GET_FIRST_REGION:
984 ret = pcmcia_get_first_region(s->handle, &buf.region);
986 case DS_GET_NEXT_REGION:
987 ret = pcmcia_get_next_region(s->handle, &buf.region);
989 case DS_GET_FIRST_WINDOW:
990 buf.win_info.handle = (window_handle_t)s->handle;
991 ret = pcmcia_get_first_window(&buf.win_info.handle, &buf.win_info.window);
993 case DS_GET_NEXT_WINDOW:
994 ret = pcmcia_get_next_window(&buf.win_info.handle, &buf.win_info.window);
996 case DS_GET_MEM_PAGE:
997 ret = pcmcia_get_mem_page(buf.win_info.handle,
1000 case DS_REPLACE_CIS:
1001 ret = pcmcia_replace_cis(s->handle, &buf.cisdump);
1003 case DS_BIND_REQUEST:
1004 if (!capable(CAP_SYS_ADMIN)) return -EPERM;
1005 err = bind_request(s, &buf.bind_info);
1007 case DS_GET_DEVICE_INFO:
1008 err = get_device_info(s, &buf.bind_info, 1);
1010 case DS_GET_NEXT_DEVICE:
1011 err = get_device_info(s, &buf.bind_info, 0);
1013 case DS_UNBIND_REQUEST:
1014 err = unbind_request(s, &buf.bind_info);
1017 if (!capable(CAP_SYS_ADMIN)) return -EPERM;
1018 err = bind_mtd(s, &buf.mtd_info);
1024 if ((err == 0) && (ret != CS_SUCCESS)) {
1025 ds_dbg(2, "ds_ioctl: ret = %d\n", ret);
1027 case CS_BAD_SOCKET: case CS_NO_CARD:
1028 err = -ENODEV; break;
1029 case CS_BAD_ARGS: case CS_BAD_ATTRIBUTE: case CS_BAD_IRQ:
1031 err = -EINVAL; break;
1033 err = -EBUSY; break;
1034 case CS_OUT_OF_RESOURCE:
1035 err = -ENOSPC; break;
1036 case CS_NO_MORE_ITEMS:
1037 err = -ENODATA; break;
1038 case CS_UNSUPPORTED_FUNCTION:
1039 err = -ENOSYS; break;
1045 if (cmd & IOC_OUT) __copy_to_user((char *)arg, (char *)&buf, size);
1050 /*====================================================================*/
1052 static struct file_operations ds_fops = {
1053 .owner = THIS_MODULE,
1055 .release = ds_release,
1062 static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev)
1064 struct pcmcia_socket *socket = class_dev->class_data;
1065 client_reg_t client_reg;
1067 struct pcmcia_bus_socket *s;
1070 s = kmalloc(sizeof(struct pcmcia_bus_socket), GFP_KERNEL);
1073 memset(s, 0, sizeof(struct pcmcia_bus_socket));
1074 atomic_set(&s->refcount, 1);
1077 * Ugly. But we want to wait for the socket threads to have started up.
1078 * We really should let the drivers themselves drive some of this..
1080 current->state = TASK_INTERRUPTIBLE;
1081 schedule_timeout(HZ/4);
1083 init_waitqueue_head(&s->queue);
1084 init_waitqueue_head(&s->request);
1086 /* initialize data */
1087 INIT_WORK(&s->removal, handle_removal, s);
1090 /* Set up hotline to Card Services */
1091 client_reg.dev_info = bind.dev_info = &dev_info;
1093 bind.Socket = socket;
1094 bind.Function = BIND_FN_ALL;
1095 ret = pcmcia_bind_device(&bind);
1096 if (ret != CS_SUCCESS) {
1097 cs_error(NULL, BindDevice, ret);
1102 client_reg.Attributes = INFO_MASTER_CLIENT;
1103 client_reg.EventMask =
1104 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
1105 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
1106 CS_EVENT_EJECTION_REQUEST | CS_EVENT_INSERTION_REQUEST |
1107 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
1108 client_reg.event_handler = &ds_event;
1109 client_reg.Version = 0x0210;
1110 client_reg.event_callback_args.client_data = s;
1111 ret = pcmcia_register_client(&s->handle, &client_reg);
1112 if (ret != CS_SUCCESS) {
1113 cs_error(NULL, RegisterClient, ret);
1124 static void pcmcia_bus_remove_socket(struct class_device *class_dev)
1126 struct pcmcia_socket *socket = class_dev->class_data;
1128 if (!socket || !socket->pcmcia)
1131 flush_scheduled_work();
1133 pcmcia_deregister_client(socket->pcmcia->handle);
1135 socket->pcmcia->state |= DS_SOCKET_DEAD;
1136 pcmcia_put_bus_socket(socket->pcmcia);
1137 socket->pcmcia = NULL;
1143 /* the pcmcia_bus_interface is used to handle pcmcia socket devices */
1144 static struct class_interface pcmcia_bus_interface = {
1145 .class = &pcmcia_socket_class,
1146 .add = &pcmcia_bus_add_socket,
1147 .remove = &pcmcia_bus_remove_socket,
1151 struct bus_type pcmcia_bus_type = {
1154 EXPORT_SYMBOL(pcmcia_bus_type);
1157 static int __init init_pcmcia_bus(void)
1161 bus_register(&pcmcia_bus_type);
1162 class_interface_register(&pcmcia_bus_interface);
1164 /* Set up character device for user mode clients */
1165 i = register_chrdev(0, "pcmcia", &ds_fops);
1167 printk(KERN_NOTICE "unable to find a free device # for "
1168 "Driver Services\n");
1172 #ifdef CONFIG_PROC_FS
1173 proc_pccard = proc_mkdir("pccard", proc_bus);
1175 create_proc_read_entry("drivers",0,proc_pccard,proc_read_drivers,NULL);
1180 fs_initcall(init_pcmcia_bus); /* one level after subsys_initcall so that
1181 * pcmcia_socket_class is already registered */
1184 static void __exit exit_pcmcia_bus(void)
1186 class_interface_unregister(&pcmcia_bus_interface);
1188 #ifdef CONFIG_PROC_FS
1190 remove_proc_entry("drivers", proc_pccard);
1191 remove_proc_entry("pccard", proc_bus);
1194 if (major_dev != -1)
1195 unregister_chrdev(major_dev, "pcmcia");
1197 bus_unregister(&pcmcia_bus_type);
1199 module_exit(exit_pcmcia_bus);
1203 /* helpers for backwards-compatible functions */
1205 static struct pcmcia_bus_socket * get_socket_info_by_nr(unsigned int nr)
1207 struct pcmcia_socket * s = pcmcia_get_socket_by_nr(nr);
1214 /* backwards-compatible accessing of driver --- by name! */
1218 struct pcmcia_driver *drv;
1221 static int cmp_drv_callback(struct device_driver *drv, void *data)
1223 struct cmp_data *cmp = data;
1224 if (strncmp((char *)cmp->dev_info, (char *)drv->name,
1225 DEV_NAME_LEN) == 0) {
1226 cmp->drv = container_of(drv, struct pcmcia_driver, drv);
1232 static struct pcmcia_driver * get_pcmcia_driver (dev_info_t *dev_info)
1235 struct cmp_data cmp = {
1236 .dev_info = dev_info,
1239 ret = bus_for_each_drv(&pcmcia_bus_type, NULL, &cmp, cmp_drv_callback);