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/delay.h>
54 #include <linux/workqueue.h>
56 #include <asm/atomic.h>
58 #define IN_CARD_SERVICES
59 #include <pcmcia/version.h>
60 #include <pcmcia/cs_types.h>
61 #include <pcmcia/cs.h>
62 #include <pcmcia/bulkmem.h>
63 #include <pcmcia/cistpl.h>
64 #include <pcmcia/ds.h>
65 #include <pcmcia/ss.h>
67 #include "cs_internal.h"
69 /*====================================================================*/
71 /* Module parameters */
73 MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
74 MODULE_DESCRIPTION("PCMCIA Driver Services");
75 MODULE_LICENSE("Dual MPL/GPL");
80 module_param_named(pc_debug, ds_pc_debug, int, 0644);
82 #define ds_dbg(lvl, fmt, arg...) do { \
83 if (ds_pc_debug > (lvl)) \
84 printk(KERN_DEBUG "ds: " fmt , ## arg); \
87 #define ds_dbg(lvl, fmt, arg...) do { } while (0)
90 /*====================================================================*/
92 typedef struct socket_bind_t {
93 struct pcmcia_driver *driver;
96 struct socket_bind_t *next;
99 /* Device user information */
100 #define MAX_EVENTS 32
101 #define USER_MAGIC 0x7ea4
102 #define CHECK_USER(u) \
103 (((u) == NULL) || ((u)->user_magic != USER_MAGIC))
104 typedef struct user_info_t {
106 int event_head, event_tail;
107 event_t event[MAX_EVENTS];
108 struct user_info_t *next;
109 struct pcmcia_bus_socket *socket;
112 /* Socket state information */
113 struct pcmcia_bus_socket {
115 client_handle_t handle;
118 int req_pending, req_result;
119 wait_queue_head_t queue, request;
120 struct work_struct removal;
122 struct pcmcia_socket *parent;
125 #define DS_SOCKET_PRESENT 0x01
126 #define DS_SOCKET_BUSY 0x02
127 #define DS_SOCKET_REMOVAL_PENDING 0x10
128 #define DS_SOCKET_DEAD 0x80
130 /*====================================================================*/
132 /* Device driver ID passed to Card Services */
133 static dev_info_t dev_info = "Driver Services";
135 static int major_dev = -1;
137 /*====================================================================*/
139 /* code which was in cs.c before */
141 /*======================================================================
143 Bind_device() associates a device driver with a particular socket.
144 It is normally called by Driver Services after it has identified
145 a newly inserted card. An instance of that driver will then be
146 eligible to register as a client of this socket.
148 ======================================================================*/
150 static int pcmcia_bind_device(bind_req_t *req)
153 struct pcmcia_socket *s;
157 return CS_BAD_SOCKET;
159 client = (client_t *) kmalloc(sizeof(client_t), GFP_KERNEL);
161 return CS_OUT_OF_RESOURCE;
162 memset(client, '\0', sizeof(client_t));
163 client->client_magic = CLIENT_MAGIC;
164 strlcpy(client->dev_info, (char *)req->dev_info, DEV_NAME_LEN);
166 client->Function = req->Function;
167 client->state = CLIENT_UNBOUND;
168 client->next = s->clients;
170 ds_dbg(1, "%s: bind_device(): client 0x%p, dev %s\n",
171 cs_socket_name(client->Socket), client, client->dev_info);
176 /*======================================================================
178 Bind_mtd() associates a device driver with a particular memory
179 region. It is normally called by Driver Services after it has
180 identified a memory device type. An instance of the corresponding
181 driver will then be able to register to control this region.
183 ======================================================================*/
185 static int pcmcia_bind_mtd(mtd_bind_t *req)
187 struct pcmcia_socket *s;
188 memory_handle_t region;
192 return CS_BAD_SOCKET;
194 if (req->Attributes & REGION_TYPE_AM)
195 region = s->a_region;
197 region = s->c_region;
200 if (region->info.CardOffset == req->CardOffset)
202 region = region->info.next;
204 if (!region || (region->mtd != NULL))
205 return CS_BAD_OFFSET;
206 strlcpy(region->dev_info, (char *)req->dev_info, DEV_NAME_LEN);
208 ds_dbg(1, "%s: bind_mtd: attr 0x%x, offset 0x%x, dev %s\n",
209 cs_socket_name(s), req->Attributes, req->CardOffset,
210 (char *)req->dev_info);
215 /* String tables for error messages */
217 typedef struct lookup_t {
222 static const lookup_t error_table[] = {
223 { CS_SUCCESS, "Operation succeeded" },
224 { CS_BAD_ADAPTER, "Bad adapter" },
225 { CS_BAD_ATTRIBUTE, "Bad attribute", },
226 { CS_BAD_BASE, "Bad base address" },
227 { CS_BAD_EDC, "Bad EDC" },
228 { CS_BAD_IRQ, "Bad IRQ" },
229 { CS_BAD_OFFSET, "Bad offset" },
230 { CS_BAD_PAGE, "Bad page number" },
231 { CS_READ_FAILURE, "Read failure" },
232 { CS_BAD_SIZE, "Bad size" },
233 { CS_BAD_SOCKET, "Bad socket" },
234 { CS_BAD_TYPE, "Bad type" },
235 { CS_BAD_VCC, "Bad Vcc" },
236 { CS_BAD_VPP, "Bad Vpp" },
237 { CS_BAD_WINDOW, "Bad window" },
238 { CS_WRITE_FAILURE, "Write failure" },
239 { CS_NO_CARD, "No card present" },
240 { CS_UNSUPPORTED_FUNCTION, "Usupported function" },
241 { CS_UNSUPPORTED_MODE, "Unsupported mode" },
242 { CS_BAD_SPEED, "Bad speed" },
243 { CS_BUSY, "Resource busy" },
244 { CS_GENERAL_FAILURE, "General failure" },
245 { CS_WRITE_PROTECTED, "Write protected" },
246 { CS_BAD_ARG_LENGTH, "Bad argument length" },
247 { CS_BAD_ARGS, "Bad arguments" },
248 { CS_CONFIGURATION_LOCKED, "Configuration locked" },
249 { CS_IN_USE, "Resource in use" },
250 { CS_NO_MORE_ITEMS, "No more items" },
251 { CS_OUT_OF_RESOURCE, "Out of resource" },
252 { CS_BAD_HANDLE, "Bad handle" },
253 { CS_BAD_TUPLE, "Bad CIS tuple" }
257 static const lookup_t service_table[] = {
258 { AccessConfigurationRegister, "AccessConfigurationRegister" },
259 { AddSocketServices, "AddSocketServices" },
260 { AdjustResourceInfo, "AdjustResourceInfo" },
261 { CheckEraseQueue, "CheckEraseQueue" },
262 { CloseMemory, "CloseMemory" },
263 { DeregisterClient, "DeregisterClient" },
264 { DeregisterEraseQueue, "DeregisterEraseQueue" },
265 { GetCardServicesInfo, "GetCardServicesInfo" },
266 { GetClientInfo, "GetClientInfo" },
267 { GetConfigurationInfo, "GetConfigurationInfo" },
268 { GetEventMask, "GetEventMask" },
269 { GetFirstClient, "GetFirstClient" },
270 { GetFirstRegion, "GetFirstRegion" },
271 { GetFirstTuple, "GetFirstTuple" },
272 { GetNextClient, "GetNextClient" },
273 { GetNextRegion, "GetNextRegion" },
274 { GetNextTuple, "GetNextTuple" },
275 { GetStatus, "GetStatus" },
276 { GetTupleData, "GetTupleData" },
277 { MapMemPage, "MapMemPage" },
278 { ModifyConfiguration, "ModifyConfiguration" },
279 { ModifyWindow, "ModifyWindow" },
280 { OpenMemory, "OpenMemory" },
281 { ParseTuple, "ParseTuple" },
282 { ReadMemory, "ReadMemory" },
283 { RegisterClient, "RegisterClient" },
284 { RegisterEraseQueue, "RegisterEraseQueue" },
285 { RegisterMTD, "RegisterMTD" },
286 { ReleaseConfiguration, "ReleaseConfiguration" },
287 { ReleaseIO, "ReleaseIO" },
288 { ReleaseIRQ, "ReleaseIRQ" },
289 { ReleaseWindow, "ReleaseWindow" },
290 { RequestConfiguration, "RequestConfiguration" },
291 { RequestIO, "RequestIO" },
292 { RequestIRQ, "RequestIRQ" },
293 { RequestSocketMask, "RequestSocketMask" },
294 { RequestWindow, "RequestWindow" },
295 { ResetCard, "ResetCard" },
296 { SetEventMask, "SetEventMask" },
297 { ValidateCIS, "ValidateCIS" },
298 { WriteMemory, "WriteMemory" },
299 { BindDevice, "BindDevice" },
300 { BindMTD, "BindMTD" },
301 { ReportError, "ReportError" },
302 { SuspendCard, "SuspendCard" },
303 { ResumeCard, "ResumeCard" },
304 { EjectCard, "EjectCard" },
305 { InsertCard, "InsertCard" },
306 { ReplaceCIS, "ReplaceCIS" }
310 int pcmcia_report_error(client_handle_t handle, error_info_t *err)
315 if (CHECK_HANDLE(handle))
318 printk(KERN_NOTICE "%s: ", handle->dev_info);
320 for (i = 0; i < ARRAY_SIZE(service_table); i++)
321 if (service_table[i].key == err->func)
323 if (i < ARRAY_SIZE(service_table))
324 serv = service_table[i].msg;
326 serv = "Unknown service number";
328 for (i = 0; i < ARRAY_SIZE(error_table); i++)
329 if (error_table[i].key == err->retcode)
331 if (i < ARRAY_SIZE(error_table))
332 printk("%s: %s\n", serv, error_table[i].msg);
334 printk("%s: Unknown error code %#x\n", serv, err->retcode);
338 EXPORT_SYMBOL(pcmcia_report_error);
340 /* end of code which was in cs.c before */
342 /*======================================================================*/
344 void cs_error(client_handle_t handle, int func, int ret)
346 error_info_t err = { func, ret };
347 pcmcia_report_error(handle, &err);
349 EXPORT_SYMBOL(cs_error);
351 /*======================================================================*/
353 static struct pcmcia_driver * get_pcmcia_driver (dev_info_t *dev_info);
354 static struct pcmcia_bus_socket * get_socket_info_by_nr(unsigned int nr);
356 static void pcmcia_put_bus_socket(struct pcmcia_bus_socket *s)
358 if (atomic_dec_and_test(&s->refcount))
362 static struct pcmcia_bus_socket *pcmcia_get_bus_socket(int nr)
364 struct pcmcia_bus_socket *s;
366 s = get_socket_info_by_nr(nr);
368 WARN_ON(atomic_read(&s->refcount) == 0);
369 atomic_inc(&s->refcount);
375 * pcmcia_register_driver - register a PCMCIA driver with the bus core
377 * Registers a PCMCIA driver with the PCMCIA bus core.
379 int pcmcia_register_driver(struct pcmcia_driver *driver)
384 driver->use_count = 0;
385 driver->drv.bus = &pcmcia_bus_type;
387 return driver_register(&driver->drv);
389 EXPORT_SYMBOL(pcmcia_register_driver);
392 * pcmcia_unregister_driver - unregister a PCMCIA driver with the bus core
394 void pcmcia_unregister_driver(struct pcmcia_driver *driver)
396 driver_unregister(&driver->drv);
398 EXPORT_SYMBOL(pcmcia_unregister_driver);
400 #ifdef CONFIG_PROC_FS
401 static struct proc_dir_entry *proc_pccard = NULL;
403 static int proc_read_drivers_callback(struct device_driver *driver, void *d)
406 struct pcmcia_driver *p_dev = container_of(driver,
407 struct pcmcia_driver, drv);
409 *p += sprintf(*p, "%-24.24s 1 %d\n", driver->name, p_dev->use_count);
415 static int proc_read_drivers(char *buf, char **start, off_t pos,
416 int count, int *eof, void *data)
420 bus_for_each_drv(&pcmcia_bus_type, NULL,
421 (void *) &p, proc_read_drivers_callback);
427 /*======================================================================
429 These manage a ring buffer of events pending for one user process
431 ======================================================================*/
433 static int queue_empty(user_info_t *user)
435 return (user->event_head == user->event_tail);
438 static event_t get_queued_event(user_info_t *user)
440 user->event_tail = (user->event_tail+1) % MAX_EVENTS;
441 return user->event[user->event_tail];
444 static void queue_event(user_info_t *user, event_t event)
446 user->event_head = (user->event_head+1) % MAX_EVENTS;
447 if (user->event_head == user->event_tail)
448 user->event_tail = (user->event_tail+1) % MAX_EVENTS;
449 user->event[user->event_head] = event;
452 static void handle_event(struct pcmcia_bus_socket *s, event_t event)
455 for (user = s->user; user; user = user->next)
456 queue_event(user, event);
457 wake_up_interruptible(&s->queue);
460 static int handle_request(struct pcmcia_bus_socket *s, event_t event)
462 if (s->req_pending != 0)
464 if (s->state & DS_SOCKET_BUSY)
466 handle_event(s, event);
467 if (wait_event_interruptible(s->request, s->req_pending <= 0))
469 if (s->state & DS_SOCKET_BUSY)
470 return s->req_result;
474 static void handle_removal(void *data)
476 struct pcmcia_bus_socket *s = data;
477 handle_event(s, CS_EVENT_CARD_REMOVAL);
478 s->state &= ~DS_SOCKET_REMOVAL_PENDING;
481 /*======================================================================
483 The card status event handler.
485 ======================================================================*/
487 static int ds_event(event_t event, int priority,
488 event_callback_args_t *args)
490 struct pcmcia_bus_socket *s;
492 ds_dbg(1, "ds_event(0x%06x, %d, 0x%p)\n",
493 event, priority, args->client_handle);
494 s = args->client_data;
498 case CS_EVENT_CARD_REMOVAL:
499 s->state &= ~DS_SOCKET_PRESENT;
500 if (!(s->state & DS_SOCKET_REMOVAL_PENDING)) {
501 s->state |= DS_SOCKET_REMOVAL_PENDING;
502 schedule_delayed_work(&s->removal, HZ/10);
506 case CS_EVENT_CARD_INSERTION:
507 s->state |= DS_SOCKET_PRESENT;
508 handle_event(s, event);
511 case CS_EVENT_EJECTION_REQUEST:
512 return handle_request(s, event);
516 handle_event(s, event);
523 /*======================================================================
525 bind_mtd() connects a memory region with an MTD client.
527 ======================================================================*/
529 static int bind_mtd(struct pcmcia_bus_socket *bus_sock, mtd_info_t *mtd_info)
534 bind_req.dev_info = &mtd_info->dev_info;
535 bind_req.Attributes = mtd_info->Attributes;
536 bind_req.Socket = bus_sock->parent;
537 bind_req.CardOffset = mtd_info->CardOffset;
538 ret = pcmcia_bind_mtd(&bind_req);
539 if (ret != CS_SUCCESS) {
540 cs_error(NULL, BindMTD, ret);
541 printk(KERN_NOTICE "ds: unable to bind MTD '%s' to socket %d"
543 (char *)bind_req.dev_info, bus_sock->parent->sock, bind_req.CardOffset);
549 /*======================================================================
551 bind_request() connects a socket to a particular client driver.
552 It looks up the specified device ID in the list of registered
553 drivers, binds it to the socket, and tries to create an instance
554 of the device. unbind_request() deletes a driver instance.
556 ======================================================================*/
558 static int bind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info)
560 struct pcmcia_driver *driver;
568 ds_dbg(2, "bind_request(%d, '%s')\n", s->parent->sock,
569 (char *)bind_info->dev_info);
570 driver = get_pcmcia_driver(&bind_info->dev_info);
574 for (b = s->bind; b; b = b->next)
575 if ((driver == b->driver) &&
576 (bind_info->function == b->function))
579 bind_info->instance = b->instance;
583 if (!try_module_get(driver->owner))
586 bind_req.Socket = s->parent;
587 bind_req.Function = bind_info->function;
588 bind_req.dev_info = (dev_info_t *) driver->drv.name;
589 ret = pcmcia_bind_device(&bind_req);
590 if (ret != CS_SUCCESS) {
591 cs_error(NULL, BindDevice, ret);
592 printk(KERN_NOTICE "ds: unable to bind '%s' to socket %d\n",
593 (char *)dev_info, s->parent->sock);
594 module_put(driver->owner);
598 /* Add binding to list for this socket */
600 b = kmalloc(sizeof(socket_bind_t), GFP_KERNEL);
604 module_put(driver->owner);
608 b->function = bind_info->function;
613 if (driver->attach) {
614 b->instance = driver->attach();
615 if (b->instance == NULL) {
616 printk(KERN_NOTICE "ds: unable to create instance "
617 "of '%s'!\n", (char *)bind_info->dev_info);
618 module_put(driver->owner);
626 /*====================================================================*/
628 extern struct pci_bus *pcmcia_lookup_bus(struct pcmcia_socket *s);
630 static int get_device_info(struct pcmcia_bus_socket *s, bind_info_t *bind_info, int first)
635 #ifdef CONFIG_CARDBUS
637 * Some unbelievably ugly code to associate the PCI cardbus
638 * device and its driver with the PCMCIA "bind" information.
643 bus = pcmcia_lookup_bus(s->parent);
645 struct list_head *list;
646 struct pci_dev *dev = NULL;
648 list = bus->devices.next;
649 while (list != &bus->devices) {
650 struct pci_dev *pdev = pci_dev_b(list);
658 /* Try to handle "next" here some way? */
660 if (dev && dev->driver) {
661 strlcpy(bind_info->name, dev->driver->name, DEV_NAME_LEN);
662 bind_info->major = 0;
663 bind_info->minor = 0;
664 bind_info->next = NULL;
671 for (b = s->bind; b; b = b->next)
672 if ((strcmp((char *)b->driver->drv.name,
673 (char *)bind_info->dev_info) == 0) &&
674 (b->function == bind_info->function))
676 if (b == NULL) return -ENODEV;
677 if ((b->instance == NULL) ||
678 (b->instance->state & DEV_CONFIG_PENDING))
681 node = b->instance->dev;
683 for (node = b->instance->dev; node; node = node->next)
684 if (node == bind_info->next) break;
685 if (node == NULL) return -ENODEV;
687 strlcpy(bind_info->name, node->dev_name, DEV_NAME_LEN);
688 bind_info->major = node->major;
689 bind_info->minor = node->minor;
690 bind_info->next = node->next;
693 } /* get_device_info */
695 /*====================================================================*/
697 static int unbind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info)
699 socket_bind_t **b, *c;
701 ds_dbg(2, "unbind_request(%d, '%s')\n", s->parent->sock,
702 (char *)bind_info->dev_info);
703 for (b = &s->bind; *b; b = &(*b)->next)
704 if ((strcmp((char *)(*b)->driver->drv.name,
705 (char *)bind_info->dev_info) == 0) &&
706 ((*b)->function == bind_info->function))
712 c->driver->use_count--;
713 if (c->driver->detach) {
715 c->driver->detach(c->instance);
717 module_put(c->driver->owner);
721 } /* unbind_request */
723 /*======================================================================
725 The user-mode PC Card device interface
727 ======================================================================*/
729 static int ds_open(struct inode *inode, struct file *file)
731 socket_t i = iminor(inode);
732 struct pcmcia_bus_socket *s;
735 ds_dbg(0, "ds_open(socket %d)\n", i);
737 s = pcmcia_get_bus_socket(i);
741 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
742 if (s->state & DS_SOCKET_BUSY)
745 s->state |= DS_SOCKET_BUSY;
748 user = kmalloc(sizeof(user_info_t), GFP_KERNEL);
749 if (!user) return -ENOMEM;
750 user->event_tail = user->event_head = 0;
751 user->next = s->user;
752 user->user_magic = USER_MAGIC;
755 file->private_data = user;
757 if (s->state & DS_SOCKET_PRESENT)
758 queue_event(user, CS_EVENT_CARD_INSERTION);
762 /*====================================================================*/
764 static int ds_release(struct inode *inode, struct file *file)
766 struct pcmcia_bus_socket *s;
767 user_info_t *user, **link;
769 ds_dbg(0, "ds_release(socket %d)\n", iminor(inode));
771 user = file->private_data;
772 if (CHECK_USER(user))
777 /* Unlink user data structure */
778 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
779 s->state &= ~DS_SOCKET_BUSY;
781 wake_up_interruptible(&s->request);
783 file->private_data = NULL;
784 for (link = &s->user; *link; link = &(*link)->next)
785 if (*link == user) break;
789 user->user_magic = 0;
791 pcmcia_put_bus_socket(s);
796 /*====================================================================*/
798 static ssize_t ds_read(struct file *file, char __user *buf,
799 size_t count, loff_t *ppos)
801 struct pcmcia_bus_socket *s;
805 ds_dbg(2, "ds_read(socket %d)\n", iminor(file->f_dentry->d_inode));
810 user = file->private_data;
811 if (CHECK_USER(user))
815 if (s->state & DS_SOCKET_DEAD)
818 ret = wait_event_interruptible(s->queue, !queue_empty(user));
820 ret = put_user(get_queued_event(user), (int __user *)buf) ? -EFAULT : 4;
825 /*====================================================================*/
827 static ssize_t ds_write(struct file *file, const char __user *buf,
828 size_t count, loff_t *ppos)
830 struct pcmcia_bus_socket *s;
833 ds_dbg(2, "ds_write(socket %d)\n", iminor(file->f_dentry->d_inode));
837 if ((file->f_flags & O_ACCMODE) == O_RDONLY)
840 user = file->private_data;
841 if (CHECK_USER(user))
845 if (s->state & DS_SOCKET_DEAD)
848 if (s->req_pending) {
850 get_user(s->req_result, (int __user *)buf);
851 if ((s->req_result != 0) || (s->req_pending == 0))
852 wake_up_interruptible(&s->request);
859 /*====================================================================*/
861 /* No kernel lock - fine */
862 static u_int ds_poll(struct file *file, poll_table *wait)
864 struct pcmcia_bus_socket *s;
867 ds_dbg(2, "ds_poll(socket %d)\n", iminor(file->f_dentry->d_inode));
869 user = file->private_data;
870 if (CHECK_USER(user))
874 * We don't check for a dead socket here since that
875 * will send cardmgr into an endless spin.
877 poll_wait(file, &s->queue, wait);
878 if (!queue_empty(user))
879 return POLLIN | POLLRDNORM;
883 /*====================================================================*/
885 extern int pcmcia_adjust_resource_info(adjust_t *adj);
886 extern int pccard_get_next_region(struct pcmcia_socket *s, region_info_t *rgn);
887 extern int pccard_get_first_region(struct pcmcia_socket *s, region_info_t *rgn);
889 static int ds_ioctl(struct inode * inode, struct file * file,
890 u_int cmd, u_long arg)
892 struct pcmcia_bus_socket *s;
893 void __user *uarg = (char __user *)arg;
899 ds_dbg(2, "ds_ioctl(socket %d, %#x, %#lx)\n", iminor(inode), cmd, arg);
901 user = file->private_data;
902 if (CHECK_USER(user))
906 if (s->state & DS_SOCKET_DEAD)
909 size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
910 if (size > sizeof(ds_ioctl_arg_t)) return -EINVAL;
912 /* Permission check */
913 if (!(cmd & IOC_OUT) && !capable(CAP_SYS_ADMIN))
917 err = verify_area(VERIFY_READ, uarg, size);
919 ds_dbg(3, "ds_ioctl(): verify_read = %d\n", err);
924 err = verify_area(VERIFY_WRITE, uarg, size);
926 ds_dbg(3, "ds_ioctl(): verify_write = %d\n", err);
933 if (cmd & IOC_IN) __copy_from_user((char *)&buf, uarg, size);
936 case DS_ADJUST_RESOURCE_INFO:
937 ret = pcmcia_adjust_resource_info(&buf.adjust);
939 case DS_GET_CARD_SERVICES_INFO:
940 ret = pcmcia_get_card_services_info(&buf.servinfo);
942 case DS_GET_CONFIGURATION_INFO:
943 if (buf.config.Function &&
944 (buf.config.Function >= s->parent->functions))
947 ret = pccard_get_configuration_info(s->parent, buf.config.Function, &buf.config);
949 case DS_GET_FIRST_TUPLE:
950 pcmcia_validate_mem(s->parent);
951 ret = pccard_get_first_tuple(s->parent, BIND_FN_ALL, &buf.tuple);
953 case DS_GET_NEXT_TUPLE:
954 ret = pccard_get_next_tuple(s->parent, BIND_FN_ALL, &buf.tuple);
956 case DS_GET_TUPLE_DATA:
957 buf.tuple.TupleData = buf.tuple_parse.data;
958 buf.tuple.TupleDataMax = sizeof(buf.tuple_parse.data);
959 ret = pccard_get_tuple_data(s->parent, &buf.tuple);
962 buf.tuple.TupleData = buf.tuple_parse.data;
963 ret = pccard_parse_tuple(&buf.tuple, &buf.tuple_parse.parse);
966 ret = pccard_reset_card(s->parent);
969 if (buf.status.Function &&
970 (buf.status.Function >= s->parent->functions))
973 ret = pccard_get_status(s->parent, buf.status.Function, &buf.status);
975 case DS_VALIDATE_CIS:
976 pcmcia_validate_mem(s->parent);
977 ret = pccard_validate_cis(s->parent, BIND_FN_ALL, &buf.cisinfo);
979 case DS_SUSPEND_CARD:
980 ret = pcmcia_suspend_card(s->parent);
983 ret = pcmcia_resume_card(s->parent);
986 err = pcmcia_eject_card(s->parent);
989 err = pcmcia_insert_card(s->parent);
991 case DS_ACCESS_CONFIGURATION_REGISTER:
992 if ((buf.conf_reg.Action == CS_WRITE) && !capable(CAP_SYS_ADMIN))
994 if (buf.conf_reg.Function &&
995 (buf.conf_reg.Function >= s->parent->functions))
998 ret = pccard_access_configuration_register(s->parent, buf.conf_reg.Function, &buf.conf_reg);
1000 case DS_GET_FIRST_REGION:
1001 ret = pccard_get_first_region(s->parent, &buf.region);
1003 case DS_GET_NEXT_REGION:
1004 ret = pccard_get_next_region(s->parent, &buf.region);
1006 case DS_GET_FIRST_WINDOW:
1007 ret = pcmcia_get_window(s->parent, &buf.win_info.handle, 0, &buf.win_info.window);
1009 case DS_GET_NEXT_WINDOW:
1010 ret = pcmcia_get_window(s->parent, &buf.win_info.handle, buf.win_info.handle->index + 1, &buf.win_info.window);
1012 case DS_GET_MEM_PAGE:
1013 ret = pcmcia_get_mem_page(buf.win_info.handle,
1016 case DS_REPLACE_CIS:
1017 ret = pcmcia_replace_cis(s->parent, &buf.cisdump);
1019 case DS_BIND_REQUEST:
1020 if (!capable(CAP_SYS_ADMIN)) return -EPERM;
1021 err = bind_request(s, &buf.bind_info);
1023 case DS_GET_DEVICE_INFO:
1024 err = get_device_info(s, &buf.bind_info, 1);
1026 case DS_GET_NEXT_DEVICE:
1027 err = get_device_info(s, &buf.bind_info, 0);
1029 case DS_UNBIND_REQUEST:
1030 err = unbind_request(s, &buf.bind_info);
1033 if (!capable(CAP_SYS_ADMIN)) return -EPERM;
1034 err = bind_mtd(s, &buf.mtd_info);
1040 if ((err == 0) && (ret != CS_SUCCESS)) {
1041 ds_dbg(2, "ds_ioctl: ret = %d\n", ret);
1043 case CS_BAD_SOCKET: case CS_NO_CARD:
1044 err = -ENODEV; break;
1045 case CS_BAD_ARGS: case CS_BAD_ATTRIBUTE: case CS_BAD_IRQ:
1047 err = -EINVAL; break;
1049 err = -EBUSY; break;
1050 case CS_OUT_OF_RESOURCE:
1051 err = -ENOSPC; break;
1052 case CS_NO_MORE_ITEMS:
1053 err = -ENODATA; break;
1054 case CS_UNSUPPORTED_FUNCTION:
1055 err = -ENOSYS; break;
1061 if (cmd & IOC_OUT) {
1062 if (__copy_to_user(uarg, (char *)&buf, size))
1070 /*====================================================================*/
1072 static struct file_operations ds_fops = {
1073 .owner = THIS_MODULE,
1075 .release = ds_release,
1082 static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev)
1084 struct pcmcia_socket *socket = class_dev->class_data;
1085 client_reg_t client_reg;
1087 struct pcmcia_bus_socket *s;
1090 s = kmalloc(sizeof(struct pcmcia_bus_socket), GFP_KERNEL);
1093 memset(s, 0, sizeof(struct pcmcia_bus_socket));
1094 atomic_set(&s->refcount, 1);
1097 * Ugly. But we want to wait for the socket threads to have started up.
1098 * We really should let the drivers themselves drive some of this..
1102 init_waitqueue_head(&s->queue);
1103 init_waitqueue_head(&s->request);
1105 /* initialize data */
1106 INIT_WORK(&s->removal, handle_removal, s);
1109 /* Set up hotline to Card Services */
1110 client_reg.dev_info = bind.dev_info = &dev_info;
1112 bind.Socket = socket;
1113 bind.Function = BIND_FN_ALL;
1114 ret = pcmcia_bind_device(&bind);
1115 if (ret != CS_SUCCESS) {
1116 cs_error(NULL, BindDevice, ret);
1121 client_reg.Attributes = INFO_MASTER_CLIENT;
1122 client_reg.EventMask =
1123 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
1124 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
1125 CS_EVENT_EJECTION_REQUEST | CS_EVENT_INSERTION_REQUEST |
1126 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
1127 client_reg.event_handler = &ds_event;
1128 client_reg.Version = 0x0210;
1129 client_reg.event_callback_args.client_data = s;
1130 ret = pcmcia_register_client(&s->handle, &client_reg);
1131 if (ret != CS_SUCCESS) {
1132 cs_error(NULL, RegisterClient, ret);
1143 static void pcmcia_bus_remove_socket(struct class_device *class_dev)
1145 struct pcmcia_socket *socket = class_dev->class_data;
1147 if (!socket || !socket->pcmcia)
1150 flush_scheduled_work();
1152 pcmcia_deregister_client(socket->pcmcia->handle);
1154 socket->pcmcia->state |= DS_SOCKET_DEAD;
1155 pcmcia_put_bus_socket(socket->pcmcia);
1156 socket->pcmcia = NULL;
1162 /* the pcmcia_bus_interface is used to handle pcmcia socket devices */
1163 static struct class_interface pcmcia_bus_interface = {
1164 .class = &pcmcia_socket_class,
1165 .add = &pcmcia_bus_add_socket,
1166 .remove = &pcmcia_bus_remove_socket,
1170 struct bus_type pcmcia_bus_type = {
1173 EXPORT_SYMBOL(pcmcia_bus_type);
1176 static int __init init_pcmcia_bus(void)
1180 bus_register(&pcmcia_bus_type);
1181 class_interface_register(&pcmcia_bus_interface);
1183 /* Set up character device for user mode clients */
1184 i = register_chrdev(0, "pcmcia", &ds_fops);
1186 printk(KERN_NOTICE "unable to find a free device # for "
1187 "Driver Services\n");
1191 #ifdef CONFIG_PROC_FS
1192 proc_pccard = proc_mkdir("pccard", proc_bus);
1194 create_proc_read_entry("drivers",0,proc_pccard,proc_read_drivers,NULL);
1199 fs_initcall(init_pcmcia_bus); /* one level after subsys_initcall so that
1200 * pcmcia_socket_class is already registered */
1203 static void __exit exit_pcmcia_bus(void)
1205 class_interface_unregister(&pcmcia_bus_interface);
1207 #ifdef CONFIG_PROC_FS
1209 remove_proc_entry("drivers", proc_pccard);
1210 remove_proc_entry("pccard", proc_bus);
1213 if (major_dev != -1)
1214 unregister_chrdev(major_dev, "pcmcia");
1216 bus_unregister(&pcmcia_bus_type);
1218 module_exit(exit_pcmcia_bus);
1222 /* helpers for backwards-compatible functions */
1224 static struct pcmcia_bus_socket * get_socket_info_by_nr(unsigned int nr)
1226 struct pcmcia_socket * s = pcmcia_get_socket_by_nr(nr);
1233 /* backwards-compatible accessing of driver --- by name! */
1237 struct pcmcia_driver *drv;
1240 static int cmp_drv_callback(struct device_driver *drv, void *data)
1242 struct cmp_data *cmp = data;
1243 if (strncmp((char *)cmp->dev_info, (char *)drv->name,
1244 DEV_NAME_LEN) == 0) {
1245 cmp->drv = container_of(drv, struct pcmcia_driver, drv);
1251 static struct pcmcia_driver * get_pcmcia_driver (dev_info_t *dev_info)
1254 struct cmp_data cmp = {
1255 .dev_info = dev_info,
1258 ret = bus_for_each_drv(&pcmcia_bus_type, NULL, &cmp, cmp_drv_callback);