MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / drivers / pcmcia / ds.c
blobb4f741a12cce07ee72c092a3026832783f482dc2
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>
43 #include <linux/mm.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");
77 #ifdef DEBUG
78 static int pc_debug;
80 module_param(pc_debug, int, 0644);
82 #define ds_dbg(lvl, fmt, arg...) do { \
83 if (pc_debug > (lvl)) \
84 printk(KERN_DEBUG "ds: " fmt , ## arg); \
85 } while (0)
86 #else
87 #define ds_dbg(lvl, fmt, arg...) do { } while (0)
88 #endif
90 /*====================================================================*/
92 typedef struct socket_bind_t {
93 struct pcmcia_driver *driver;
94 u_char function;
95 dev_link_t *instance;
96 struct socket_bind_t *next;
97 } socket_bind_t;
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 {
105 u_int user_magic;
106 int event_head, event_tail;
107 event_t event[MAX_EVENTS];
108 struct user_info_t *next;
109 struct pcmcia_bus_socket *socket;
110 } user_info_t;
112 /* Socket state information */
113 struct pcmcia_bus_socket {
114 atomic_t refcount;
115 client_handle_t handle;
116 int state;
117 user_info_t *user;
118 int req_pending, req_result;
119 wait_queue_head_t queue, request;
120 struct work_struct removal;
121 socket_bind_t *bind;
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 static struct proc_dir_entry *proc_pccard;
139 /*====================================================================*/
141 /* code which was in cs.c before */
143 /*======================================================================
145 Bind_device() associates a device driver with a particular socket.
146 It is normally called by Driver Services after it has identified
147 a newly inserted card. An instance of that driver will then be
148 eligible to register as a client of this socket.
150 ======================================================================*/
152 static int pcmcia_bind_device(bind_req_t *req)
154 client_t *client;
155 struct pcmcia_socket *s;
157 s = req->Socket;
158 if (!s)
159 return CS_BAD_SOCKET;
161 client = (client_t *) kmalloc(sizeof(client_t), GFP_KERNEL);
162 if (!client)
163 return CS_OUT_OF_RESOURCE;
164 memset(client, '\0', sizeof(client_t));
165 client->client_magic = CLIENT_MAGIC;
166 strlcpy(client->dev_info, (char *)req->dev_info, DEV_NAME_LEN);
167 client->Socket = s;
168 client->Function = req->Function;
169 client->state = CLIENT_UNBOUND;
170 client->erase_busy.next = &client->erase_busy;
171 client->erase_busy.prev = &client->erase_busy;
172 init_waitqueue_head(&client->mtd_req);
173 client->next = s->clients;
174 s->clients = client;
175 ds_dbg(1, "%s: bind_device(): client 0x%p, dev %s\n",
176 cs_socket_name(client->Socket), client, client->dev_info);
177 return CS_SUCCESS;
178 } /* bind_device */
181 /*======================================================================
183 Bind_mtd() associates a device driver with a particular memory
184 region. It is normally called by Driver Services after it has
185 identified a memory device type. An instance of the corresponding
186 driver will then be able to register to control this region.
188 ======================================================================*/
190 static int pcmcia_bind_mtd(mtd_bind_t *req)
192 struct pcmcia_socket *s;
193 memory_handle_t region;
195 s = req->Socket;
196 if (!s)
197 return CS_BAD_SOCKET;
199 if (req->Attributes & REGION_TYPE_AM)
200 region = s->a_region;
201 else
202 region = s->c_region;
204 while (region) {
205 if (region->info.CardOffset == req->CardOffset)
206 break;
207 region = region->info.next;
209 if (!region || (region->mtd != NULL))
210 return CS_BAD_OFFSET;
211 strlcpy(region->dev_info, (char *)req->dev_info, DEV_NAME_LEN);
213 ds_dbg(1, "%s: bind_mtd: attr 0x%x, offset 0x%x, dev %s\n",
214 cs_socket_name(s), req->Attributes, req->CardOffset,
215 (char *)req->dev_info);
216 return CS_SUCCESS;
217 } /* bind_mtd */
220 /* String tables for error messages */
222 typedef struct lookup_t {
223 int key;
224 char *msg;
225 } lookup_t;
227 static const lookup_t error_table[] = {
228 { CS_SUCCESS, "Operation succeeded" },
229 { CS_BAD_ADAPTER, "Bad adapter" },
230 { CS_BAD_ATTRIBUTE, "Bad attribute", },
231 { CS_BAD_BASE, "Bad base address" },
232 { CS_BAD_EDC, "Bad EDC" },
233 { CS_BAD_IRQ, "Bad IRQ" },
234 { CS_BAD_OFFSET, "Bad offset" },
235 { CS_BAD_PAGE, "Bad page number" },
236 { CS_READ_FAILURE, "Read failure" },
237 { CS_BAD_SIZE, "Bad size" },
238 { CS_BAD_SOCKET, "Bad socket" },
239 { CS_BAD_TYPE, "Bad type" },
240 { CS_BAD_VCC, "Bad Vcc" },
241 { CS_BAD_VPP, "Bad Vpp" },
242 { CS_BAD_WINDOW, "Bad window" },
243 { CS_WRITE_FAILURE, "Write failure" },
244 { CS_NO_CARD, "No card present" },
245 { CS_UNSUPPORTED_FUNCTION, "Usupported function" },
246 { CS_UNSUPPORTED_MODE, "Unsupported mode" },
247 { CS_BAD_SPEED, "Bad speed" },
248 { CS_BUSY, "Resource busy" },
249 { CS_GENERAL_FAILURE, "General failure" },
250 { CS_WRITE_PROTECTED, "Write protected" },
251 { CS_BAD_ARG_LENGTH, "Bad argument length" },
252 { CS_BAD_ARGS, "Bad arguments" },
253 { CS_CONFIGURATION_LOCKED, "Configuration locked" },
254 { CS_IN_USE, "Resource in use" },
255 { CS_NO_MORE_ITEMS, "No more items" },
256 { CS_OUT_OF_RESOURCE, "Out of resource" },
257 { CS_BAD_HANDLE, "Bad handle" },
258 { CS_BAD_TUPLE, "Bad CIS tuple" }
262 static const lookup_t service_table[] = {
263 { AccessConfigurationRegister, "AccessConfigurationRegister" },
264 { AddSocketServices, "AddSocketServices" },
265 { AdjustResourceInfo, "AdjustResourceInfo" },
266 { CheckEraseQueue, "CheckEraseQueue" },
267 { CloseMemory, "CloseMemory" },
268 { DeregisterClient, "DeregisterClient" },
269 { DeregisterEraseQueue, "DeregisterEraseQueue" },
270 { GetCardServicesInfo, "GetCardServicesInfo" },
271 { GetClientInfo, "GetClientInfo" },
272 { GetConfigurationInfo, "GetConfigurationInfo" },
273 { GetEventMask, "GetEventMask" },
274 { GetFirstClient, "GetFirstClient" },
275 { GetFirstRegion, "GetFirstRegion" },
276 { GetFirstTuple, "GetFirstTuple" },
277 { GetNextClient, "GetNextClient" },
278 { GetNextRegion, "GetNextRegion" },
279 { GetNextTuple, "GetNextTuple" },
280 { GetStatus, "GetStatus" },
281 { GetTupleData, "GetTupleData" },
282 { MapMemPage, "MapMemPage" },
283 { ModifyConfiguration, "ModifyConfiguration" },
284 { ModifyWindow, "ModifyWindow" },
285 { OpenMemory, "OpenMemory" },
286 { ParseTuple, "ParseTuple" },
287 { ReadMemory, "ReadMemory" },
288 { RegisterClient, "RegisterClient" },
289 { RegisterEraseQueue, "RegisterEraseQueue" },
290 { RegisterMTD, "RegisterMTD" },
291 { ReleaseConfiguration, "ReleaseConfiguration" },
292 { ReleaseIO, "ReleaseIO" },
293 { ReleaseIRQ, "ReleaseIRQ" },
294 { ReleaseWindow, "ReleaseWindow" },
295 { RequestConfiguration, "RequestConfiguration" },
296 { RequestIO, "RequestIO" },
297 { RequestIRQ, "RequestIRQ" },
298 { RequestSocketMask, "RequestSocketMask" },
299 { RequestWindow, "RequestWindow" },
300 { ResetCard, "ResetCard" },
301 { SetEventMask, "SetEventMask" },
302 { ValidateCIS, "ValidateCIS" },
303 { WriteMemory, "WriteMemory" },
304 { BindDevice, "BindDevice" },
305 { BindMTD, "BindMTD" },
306 { ReportError, "ReportError" },
307 { SuspendCard, "SuspendCard" },
308 { ResumeCard, "ResumeCard" },
309 { EjectCard, "EjectCard" },
310 { InsertCard, "InsertCard" },
311 { ReplaceCIS, "ReplaceCIS" }
315 int pcmcia_report_error(client_handle_t handle, error_info_t *err)
317 int i;
318 char *serv;
320 if (CHECK_HANDLE(handle))
321 printk(KERN_NOTICE);
322 else
323 printk(KERN_NOTICE "%s: ", handle->dev_info);
325 for (i = 0; i < ARRAY_SIZE(service_table); i++)
326 if (service_table[i].key == err->func)
327 break;
328 if (i < ARRAY_SIZE(service_table))
329 serv = service_table[i].msg;
330 else
331 serv = "Unknown service number";
333 for (i = 0; i < ARRAY_SIZE(error_table); i++)
334 if (error_table[i].key == err->retcode)
335 break;
336 if (i < ARRAY_SIZE(error_table))
337 printk("%s: %s\n", serv, error_table[i].msg);
338 else
339 printk("%s: Unknown error code %#x\n", serv, err->retcode);
341 return CS_SUCCESS;
342 } /* report_error */
343 EXPORT_SYMBOL(pcmcia_report_error);
345 /* end of code which was in cs.c before */
347 /*======================================================================*/
349 void cs_error(client_handle_t handle, int func, int ret)
351 error_info_t err = { func, ret };
352 pcmcia_report_error(handle, &err);
354 EXPORT_SYMBOL(cs_error);
356 /*======================================================================*/
358 static struct pcmcia_driver * get_pcmcia_driver (dev_info_t *dev_info);
359 static struct pcmcia_bus_socket * get_socket_info_by_nr(unsigned int nr);
361 static void pcmcia_put_bus_socket(struct pcmcia_bus_socket *s)
363 if (atomic_dec_and_test(&s->refcount))
364 kfree(s);
367 static struct pcmcia_bus_socket *pcmcia_get_bus_socket(int nr)
369 struct pcmcia_bus_socket *s;
371 s = get_socket_info_by_nr(nr);
372 if (s) {
373 WARN_ON(atomic_read(&s->refcount) == 0);
374 atomic_inc(&s->refcount);
376 return s;
380 * pcmcia_register_driver - register a PCMCIA driver with the bus core
382 * Registers a PCMCIA driver with the PCMCIA bus core.
384 int pcmcia_register_driver(struct pcmcia_driver *driver)
386 if (!driver)
387 return -EINVAL;
389 driver->use_count = 0;
390 driver->drv.bus = &pcmcia_bus_type;
392 return driver_register(&driver->drv);
394 EXPORT_SYMBOL(pcmcia_register_driver);
397 * pcmcia_unregister_driver - unregister a PCMCIA driver with the bus core
399 void pcmcia_unregister_driver(struct pcmcia_driver *driver)
401 driver_unregister(&driver->drv);
403 EXPORT_SYMBOL(pcmcia_unregister_driver);
405 #ifdef CONFIG_PROC_FS
406 static struct proc_dir_entry *proc_pccard = NULL;
408 static int proc_read_drivers_callback(struct device_driver *driver, void *d)
410 char **p = d;
411 struct pcmcia_driver *p_dev = container_of(driver,
412 struct pcmcia_driver, drv);
414 *p += sprintf(*p, "%-24.24s 1 %d\n", driver->name, p_dev->use_count);
415 d = (void *) p;
417 return 0;
420 static int proc_read_drivers(char *buf, char **start, off_t pos,
421 int count, int *eof, void *data)
423 char *p = buf;
425 bus_for_each_drv(&pcmcia_bus_type, NULL,
426 (void *) &p, proc_read_drivers_callback);
428 return (p - buf);
430 #endif
432 /*======================================================================
434 These manage a ring buffer of events pending for one user process
436 ======================================================================*/
438 static int queue_empty(user_info_t *user)
440 return (user->event_head == user->event_tail);
443 static event_t get_queued_event(user_info_t *user)
445 user->event_tail = (user->event_tail+1) % MAX_EVENTS;
446 return user->event[user->event_tail];
449 static void queue_event(user_info_t *user, event_t event)
451 user->event_head = (user->event_head+1) % MAX_EVENTS;
452 if (user->event_head == user->event_tail)
453 user->event_tail = (user->event_tail+1) % MAX_EVENTS;
454 user->event[user->event_head] = event;
457 static void handle_event(struct pcmcia_bus_socket *s, event_t event)
459 user_info_t *user;
460 for (user = s->user; user; user = user->next)
461 queue_event(user, event);
462 wake_up_interruptible(&s->queue);
465 static int handle_request(struct pcmcia_bus_socket *s, event_t event)
467 if (s->req_pending != 0)
468 return CS_IN_USE;
469 if (s->state & DS_SOCKET_BUSY)
470 s->req_pending = 1;
471 handle_event(s, event);
472 if (wait_event_interruptible(s->request, s->req_pending <= 0))
473 return CS_IN_USE;
474 if (s->state & DS_SOCKET_BUSY)
475 return s->req_result;
476 return CS_SUCCESS;
479 static void handle_removal(void *data)
481 struct pcmcia_bus_socket *s = data;
482 handle_event(s, CS_EVENT_CARD_REMOVAL);
483 s->state &= ~DS_SOCKET_REMOVAL_PENDING;
486 /*======================================================================
488 The card status event handler.
490 ======================================================================*/
492 static int ds_event(event_t event, int priority,
493 event_callback_args_t *args)
495 struct pcmcia_bus_socket *s;
497 ds_dbg(1, "ds_event(0x%06x, %d, 0x%p)\n",
498 event, priority, args->client_handle);
499 s = args->client_data;
501 switch (event) {
503 case CS_EVENT_CARD_REMOVAL:
504 s->state &= ~DS_SOCKET_PRESENT;
505 if (!(s->state & DS_SOCKET_REMOVAL_PENDING)) {
506 s->state |= DS_SOCKET_REMOVAL_PENDING;
507 schedule_delayed_work(&s->removal, HZ/10);
509 break;
511 case CS_EVENT_CARD_INSERTION:
512 s->state |= DS_SOCKET_PRESENT;
513 handle_event(s, event);
514 break;
516 case CS_EVENT_EJECTION_REQUEST:
517 return handle_request(s, event);
518 break;
520 default:
521 handle_event(s, event);
522 break;
525 return 0;
526 } /* ds_event */
528 /*======================================================================
530 bind_mtd() connects a memory region with an MTD client.
532 ======================================================================*/
534 static int bind_mtd(struct pcmcia_bus_socket *bus_sock, mtd_info_t *mtd_info)
536 mtd_bind_t bind_req;
537 int ret;
539 bind_req.dev_info = &mtd_info->dev_info;
540 bind_req.Attributes = mtd_info->Attributes;
541 bind_req.Socket = bus_sock->parent;
542 bind_req.CardOffset = mtd_info->CardOffset;
543 ret = pcmcia_bind_mtd(&bind_req);
544 if (ret != CS_SUCCESS) {
545 cs_error(NULL, BindMTD, ret);
546 printk(KERN_NOTICE "ds: unable to bind MTD '%s' to socket %d"
547 " offset 0x%x\n",
548 (char *)bind_req.dev_info, bus_sock->parent->sock, bind_req.CardOffset);
549 return -ENODEV;
551 return 0;
552 } /* bind_mtd */
554 /*======================================================================
556 bind_request() connects a socket to a particular client driver.
557 It looks up the specified device ID in the list of registered
558 drivers, binds it to the socket, and tries to create an instance
559 of the device. unbind_request() deletes a driver instance.
561 ======================================================================*/
563 static int bind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info)
565 struct pcmcia_driver *driver;
566 socket_bind_t *b;
567 bind_req_t bind_req;
568 int ret;
570 if (!s)
571 return -EINVAL;
573 ds_dbg(2, "bind_request(%d, '%s')\n", s->parent->sock,
574 (char *)bind_info->dev_info);
575 driver = get_pcmcia_driver(&bind_info->dev_info);
576 if (!driver)
577 return -EINVAL;
579 for (b = s->bind; b; b = b->next)
580 if ((driver == b->driver) &&
581 (bind_info->function == b->function))
582 break;
583 if (b != NULL) {
584 bind_info->instance = b->instance;
585 return -EBUSY;
588 if (!try_module_get(driver->owner))
589 return -EINVAL;
591 bind_req.Socket = s->parent;
592 bind_req.Function = bind_info->function;
593 bind_req.dev_info = (dev_info_t *) driver->drv.name;
594 ret = pcmcia_bind_device(&bind_req);
595 if (ret != CS_SUCCESS) {
596 cs_error(NULL, BindDevice, ret);
597 printk(KERN_NOTICE "ds: unable to bind '%s' to socket %d\n",
598 (char *)dev_info, s->parent->sock);
599 module_put(driver->owner);
600 return -ENODEV;
603 /* Add binding to list for this socket */
604 driver->use_count++;
605 b = kmalloc(sizeof(socket_bind_t), GFP_KERNEL);
606 if (!b)
608 driver->use_count--;
609 module_put(driver->owner);
610 return -ENOMEM;
612 b->driver = driver;
613 b->function = bind_info->function;
614 b->instance = NULL;
615 b->next = s->bind;
616 s->bind = b;
618 if (driver->attach) {
619 b->instance = driver->attach();
620 if (b->instance == NULL) {
621 printk(KERN_NOTICE "ds: unable to create instance "
622 "of '%s'!\n", (char *)bind_info->dev_info);
623 module_put(driver->owner);
624 return -ENODEV;
628 return 0;
629 } /* bind_request */
631 /*====================================================================*/
633 static int get_device_info(struct pcmcia_bus_socket *s, bind_info_t *bind_info, int first)
635 socket_bind_t *b;
636 dev_node_t *node;
638 #ifdef CONFIG_CARDBUS
640 * Some unbelievably ugly code to associate the PCI cardbus
641 * device and its driver with the PCMCIA "bind" information.
644 struct pci_bus *bus;
646 bus = pcmcia_lookup_bus(s->handle);
647 if (bus) {
648 struct list_head *list;
649 struct pci_dev *dev = NULL;
651 list = bus->devices.next;
652 while (list != &bus->devices) {
653 struct pci_dev *pdev = pci_dev_b(list);
654 list = list->next;
656 if (first) {
657 dev = pdev;
658 break;
661 /* Try to handle "next" here some way? */
663 if (dev && dev->driver) {
664 strlcpy(bind_info->name, dev->driver->name, DEV_NAME_LEN);
665 bind_info->major = 0;
666 bind_info->minor = 0;
667 bind_info->next = NULL;
668 return 0;
672 #endif
674 for (b = s->bind; b; b = b->next)
675 if ((strcmp((char *)b->driver->drv.name,
676 (char *)bind_info->dev_info) == 0) &&
677 (b->function == bind_info->function))
678 break;
679 if (b == NULL) return -ENODEV;
680 if ((b->instance == NULL) ||
681 (b->instance->state & DEV_CONFIG_PENDING))
682 return -EAGAIN;
683 if (first)
684 node = b->instance->dev;
685 else
686 for (node = b->instance->dev; node; node = node->next)
687 if (node == bind_info->next) break;
688 if (node == NULL) return -ENODEV;
690 strlcpy(bind_info->name, node->dev_name, DEV_NAME_LEN);
691 bind_info->major = node->major;
692 bind_info->minor = node->minor;
693 bind_info->next = node->next;
695 return 0;
696 } /* get_device_info */
698 /*====================================================================*/
700 static int unbind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info)
702 socket_bind_t **b, *c;
704 ds_dbg(2, "unbind_request(%d, '%s')\n", s->parent->sock,
705 (char *)bind_info->dev_info);
706 for (b = &s->bind; *b; b = &(*b)->next)
707 if ((strcmp((char *)(*b)->driver->drv.name,
708 (char *)bind_info->dev_info) == 0) &&
709 ((*b)->function == bind_info->function))
710 break;
711 if (*b == NULL)
712 return -ENODEV;
714 c = *b;
715 c->driver->use_count--;
716 if (c->driver->detach) {
717 if (c->instance)
718 c->driver->detach(c->instance);
720 module_put(c->driver->owner);
721 *b = c->next;
722 kfree(c);
723 return 0;
724 } /* unbind_request */
726 /*======================================================================
728 The user-mode PC Card device interface
730 ======================================================================*/
732 static int ds_open(struct inode *inode, struct file *file)
734 socket_t i = iminor(inode);
735 struct pcmcia_bus_socket *s;
736 user_info_t *user;
738 ds_dbg(0, "ds_open(socket %d)\n", i);
740 s = pcmcia_get_bus_socket(i);
741 if (!s)
742 return -ENODEV;
744 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
745 if (s->state & DS_SOCKET_BUSY)
746 return -EBUSY;
747 else
748 s->state |= DS_SOCKET_BUSY;
751 user = kmalloc(sizeof(user_info_t), GFP_KERNEL);
752 if (!user) return -ENOMEM;
753 user->event_tail = user->event_head = 0;
754 user->next = s->user;
755 user->user_magic = USER_MAGIC;
756 user->socket = s;
757 s->user = user;
758 file->private_data = user;
760 if (s->state & DS_SOCKET_PRESENT)
761 queue_event(user, CS_EVENT_CARD_INSERTION);
762 return 0;
763 } /* ds_open */
765 /*====================================================================*/
767 static int ds_release(struct inode *inode, struct file *file)
769 struct pcmcia_bus_socket *s;
770 user_info_t *user, **link;
772 ds_dbg(0, "ds_release(socket %d)\n", iminor(inode));
774 user = file->private_data;
775 if (CHECK_USER(user))
776 goto out;
778 s = user->socket;
780 /* Unlink user data structure */
781 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
782 s->state &= ~DS_SOCKET_BUSY;
783 s->req_pending = 0;
784 wake_up_interruptible(&s->request);
786 file->private_data = NULL;
787 for (link = &s->user; *link; link = &(*link)->next)
788 if (*link == user) break;
789 if (link == NULL)
790 goto out;
791 *link = user->next;
792 user->user_magic = 0;
793 kfree(user);
794 pcmcia_put_bus_socket(s);
795 out:
796 return 0;
797 } /* ds_release */
799 /*====================================================================*/
801 static ssize_t ds_read(struct file *file, char __user *buf,
802 size_t count, loff_t *ppos)
804 struct pcmcia_bus_socket *s;
805 user_info_t *user;
806 int ret;
808 ds_dbg(2, "ds_read(socket %d)\n", iminor(file->f_dentry->d_inode));
810 if (count < 4)
811 return -EINVAL;
813 user = file->private_data;
814 if (CHECK_USER(user))
815 return -EIO;
817 s = user->socket;
818 if (s->state & DS_SOCKET_DEAD)
819 return -EIO;
821 ret = wait_event_interruptible(s->queue, !queue_empty(user));
822 if (ret == 0)
823 ret = put_user(get_queued_event(user), (int __user *)buf) ? -EFAULT : 4;
825 return ret;
826 } /* ds_read */
828 /*====================================================================*/
830 static ssize_t ds_write(struct file *file, const char __user *buf,
831 size_t count, loff_t *ppos)
833 struct pcmcia_bus_socket *s;
834 user_info_t *user;
836 ds_dbg(2, "ds_write(socket %d)\n", iminor(file->f_dentry->d_inode));
838 if (count != 4)
839 return -EINVAL;
840 if ((file->f_flags & O_ACCMODE) == O_RDONLY)
841 return -EBADF;
843 user = file->private_data;
844 if (CHECK_USER(user))
845 return -EIO;
847 s = user->socket;
848 if (s->state & DS_SOCKET_DEAD)
849 return -EIO;
851 if (s->req_pending) {
852 s->req_pending--;
853 get_user(s->req_result, (int __user *)buf);
854 if ((s->req_result != 0) || (s->req_pending == 0))
855 wake_up_interruptible(&s->request);
856 } else
857 return -EIO;
859 return 4;
860 } /* ds_write */
862 /*====================================================================*/
864 /* No kernel lock - fine */
865 static u_int ds_poll(struct file *file, poll_table *wait)
867 struct pcmcia_bus_socket *s;
868 user_info_t *user;
870 ds_dbg(2, "ds_poll(socket %d)\n", iminor(file->f_dentry->d_inode));
872 user = file->private_data;
873 if (CHECK_USER(user))
874 return POLLERR;
875 s = user->socket;
877 * We don't check for a dead socket here since that
878 * will send cardmgr into an endless spin.
880 poll_wait(file, &s->queue, wait);
881 if (!queue_empty(user))
882 return POLLIN | POLLRDNORM;
883 return 0;
884 } /* ds_poll */
886 /*====================================================================*/
888 static int ds_ioctl(struct inode * inode, struct file * file,
889 u_int cmd, u_long arg)
891 struct pcmcia_bus_socket *s;
892 void __user *uarg = (char __user *)arg;
893 u_int size;
894 int ret, err;
895 ds_ioctl_arg_t buf;
896 user_info_t *user;
898 ds_dbg(2, "ds_ioctl(socket %d, %#x, %#lx)\n", iminor(inode), cmd, arg);
900 user = file->private_data;
901 if (CHECK_USER(user))
902 return -EIO;
904 s = user->socket;
905 if (s->state & DS_SOCKET_DEAD)
906 return -EIO;
908 size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
909 if (size > sizeof(ds_ioctl_arg_t)) return -EINVAL;
911 /* Permission check */
912 if (!(cmd & IOC_OUT) && !capable(CAP_SYS_ADMIN))
913 return -EPERM;
915 if (cmd & IOC_IN) {
916 err = verify_area(VERIFY_READ, uarg, size);
917 if (err) {
918 ds_dbg(3, "ds_ioctl(): verify_read = %d\n", err);
919 return err;
922 if (cmd & IOC_OUT) {
923 err = verify_area(VERIFY_WRITE, uarg, size);
924 if (err) {
925 ds_dbg(3, "ds_ioctl(): verify_write = %d\n", err);
926 return err;
930 err = ret = 0;
932 if (cmd & IOC_IN) __copy_from_user((char *)&buf, uarg, size);
934 switch (cmd) {
935 case DS_ADJUST_RESOURCE_INFO:
936 ret = pcmcia_adjust_resource_info(s->handle, &buf.adjust);
937 break;
938 case DS_GET_CARD_SERVICES_INFO:
939 ret = pcmcia_get_card_services_info(&buf.servinfo);
940 break;
941 case DS_GET_CONFIGURATION_INFO:
942 ret = pcmcia_get_configuration_info(s->handle, &buf.config);
943 break;
944 case DS_GET_FIRST_TUPLE:
945 pcmcia_validate_mem(s->parent);
946 ret = pcmcia_get_first_tuple(s->handle, &buf.tuple);
947 break;
948 case DS_GET_NEXT_TUPLE:
949 ret = pcmcia_get_next_tuple(s->handle, &buf.tuple);
950 break;
951 case DS_GET_TUPLE_DATA:
952 buf.tuple.TupleData = buf.tuple_parse.data;
953 buf.tuple.TupleDataMax = sizeof(buf.tuple_parse.data);
954 ret = pcmcia_get_tuple_data(s->handle, &buf.tuple);
955 break;
956 case DS_PARSE_TUPLE:
957 buf.tuple.TupleData = buf.tuple_parse.data;
958 ret = pcmcia_parse_tuple(s->handle, &buf.tuple, &buf.tuple_parse.parse);
959 break;
960 case DS_RESET_CARD:
961 ret = pcmcia_reset_card(s->handle, NULL);
962 break;
963 case DS_GET_STATUS:
964 ret = pcmcia_get_status(s->handle, &buf.status);
965 break;
966 case DS_VALIDATE_CIS:
967 pcmcia_validate_mem(s->parent);
968 ret = pcmcia_validate_cis(s->handle, &buf.cisinfo);
969 break;
970 case DS_SUSPEND_CARD:
971 ret = pcmcia_suspend_card(s->parent);
972 break;
973 case DS_RESUME_CARD:
974 ret = pcmcia_resume_card(s->parent);
975 break;
976 case DS_EJECT_CARD:
977 err = pcmcia_eject_card(s->parent);
978 break;
979 case DS_INSERT_CARD:
980 err = pcmcia_insert_card(s->parent);
981 break;
982 case DS_ACCESS_CONFIGURATION_REGISTER:
983 if ((buf.conf_reg.Action == CS_WRITE) && !capable(CAP_SYS_ADMIN))
984 return -EPERM;
985 ret = pcmcia_access_configuration_register(s->handle, &buf.conf_reg);
986 break;
987 case DS_GET_FIRST_REGION:
988 ret = pcmcia_get_first_region(s->handle, &buf.region);
989 break;
990 case DS_GET_NEXT_REGION:
991 ret = pcmcia_get_next_region(s->handle, &buf.region);
992 break;
993 case DS_GET_FIRST_WINDOW:
994 buf.win_info.handle = (window_handle_t)s->handle;
995 ret = pcmcia_get_first_window(&buf.win_info.handle, &buf.win_info.window);
996 break;
997 case DS_GET_NEXT_WINDOW:
998 ret = pcmcia_get_next_window(&buf.win_info.handle, &buf.win_info.window);
999 break;
1000 case DS_GET_MEM_PAGE:
1001 ret = pcmcia_get_mem_page(buf.win_info.handle,
1002 &buf.win_info.map);
1003 break;
1004 case DS_REPLACE_CIS:
1005 ret = pcmcia_replace_cis(s->handle, &buf.cisdump);
1006 break;
1007 case DS_BIND_REQUEST:
1008 if (!capable(CAP_SYS_ADMIN)) return -EPERM;
1009 err = bind_request(s, &buf.bind_info);
1010 break;
1011 case DS_GET_DEVICE_INFO:
1012 err = get_device_info(s, &buf.bind_info, 1);
1013 break;
1014 case DS_GET_NEXT_DEVICE:
1015 err = get_device_info(s, &buf.bind_info, 0);
1016 break;
1017 case DS_UNBIND_REQUEST:
1018 err = unbind_request(s, &buf.bind_info);
1019 break;
1020 case DS_BIND_MTD:
1021 if (!capable(CAP_SYS_ADMIN)) return -EPERM;
1022 err = bind_mtd(s, &buf.mtd_info);
1023 break;
1024 default:
1025 err = -EINVAL;
1028 if ((err == 0) && (ret != CS_SUCCESS)) {
1029 ds_dbg(2, "ds_ioctl: ret = %d\n", ret);
1030 switch (ret) {
1031 case CS_BAD_SOCKET: case CS_NO_CARD:
1032 err = -ENODEV; break;
1033 case CS_BAD_ARGS: case CS_BAD_ATTRIBUTE: case CS_BAD_IRQ:
1034 case CS_BAD_TUPLE:
1035 err = -EINVAL; break;
1036 case CS_IN_USE:
1037 err = -EBUSY; break;
1038 case CS_OUT_OF_RESOURCE:
1039 err = -ENOSPC; break;
1040 case CS_NO_MORE_ITEMS:
1041 err = -ENODATA; break;
1042 case CS_UNSUPPORTED_FUNCTION:
1043 err = -ENOSYS; break;
1044 default:
1045 err = -EIO; break;
1049 if (cmd & IOC_OUT) __copy_to_user(uarg, (char *)&buf, size);
1051 return err;
1052 } /* ds_ioctl */
1054 /*====================================================================*/
1056 static struct file_operations ds_fops = {
1057 .owner = THIS_MODULE,
1058 .open = ds_open,
1059 .release = ds_release,
1060 .ioctl = ds_ioctl,
1061 .read = ds_read,
1062 .write = ds_write,
1063 .poll = ds_poll,
1066 static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev)
1068 struct pcmcia_socket *socket = class_dev->class_data;
1069 client_reg_t client_reg;
1070 bind_req_t bind;
1071 struct pcmcia_bus_socket *s;
1072 int ret;
1074 s = kmalloc(sizeof(struct pcmcia_bus_socket), GFP_KERNEL);
1075 if(!s)
1076 return -ENOMEM;
1077 memset(s, 0, sizeof(struct pcmcia_bus_socket));
1078 atomic_set(&s->refcount, 1);
1081 * Ugly. But we want to wait for the socket threads to have started up.
1082 * We really should let the drivers themselves drive some of this..
1084 msleep(250);
1086 init_waitqueue_head(&s->queue);
1087 init_waitqueue_head(&s->request);
1089 /* initialize data */
1090 INIT_WORK(&s->removal, handle_removal, s);
1091 s->parent = socket;
1093 /* Set up hotline to Card Services */
1094 client_reg.dev_info = bind.dev_info = &dev_info;
1096 bind.Socket = socket;
1097 bind.Function = BIND_FN_ALL;
1098 ret = pcmcia_bind_device(&bind);
1099 if (ret != CS_SUCCESS) {
1100 cs_error(NULL, BindDevice, ret);
1101 kfree(s);
1102 return -EINVAL;
1105 client_reg.Attributes = INFO_MASTER_CLIENT;
1106 client_reg.EventMask =
1107 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
1108 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
1109 CS_EVENT_EJECTION_REQUEST | CS_EVENT_INSERTION_REQUEST |
1110 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
1111 client_reg.event_handler = &ds_event;
1112 client_reg.Version = 0x0210;
1113 client_reg.event_callback_args.client_data = s;
1114 ret = pcmcia_register_client(&s->handle, &client_reg);
1115 if (ret != CS_SUCCESS) {
1116 cs_error(NULL, RegisterClient, ret);
1117 kfree(s);
1118 return -EINVAL;
1121 socket->pcmcia = s;
1123 return 0;
1127 static void pcmcia_bus_remove_socket(struct class_device *class_dev)
1129 struct pcmcia_socket *socket = class_dev->class_data;
1131 if (!socket || !socket->pcmcia)
1132 return;
1134 flush_scheduled_work();
1136 pcmcia_deregister_client(socket->pcmcia->handle);
1138 socket->pcmcia->state |= DS_SOCKET_DEAD;
1139 pcmcia_put_bus_socket(socket->pcmcia);
1140 socket->pcmcia = NULL;
1142 return;
1146 /* the pcmcia_bus_interface is used to handle pcmcia socket devices */
1147 static struct class_interface pcmcia_bus_interface = {
1148 .class = &pcmcia_socket_class,
1149 .add = &pcmcia_bus_add_socket,
1150 .remove = &pcmcia_bus_remove_socket,
1154 struct bus_type pcmcia_bus_type = {
1155 .name = "pcmcia",
1157 EXPORT_SYMBOL(pcmcia_bus_type);
1160 static int __init init_pcmcia_bus(void)
1162 int i;
1164 bus_register(&pcmcia_bus_type);
1165 class_interface_register(&pcmcia_bus_interface);
1167 /* Set up character device for user mode clients */
1168 i = register_chrdev(0, "pcmcia", &ds_fops);
1169 if (i == -EBUSY)
1170 printk(KERN_NOTICE "unable to find a free device # for "
1171 "Driver Services\n");
1172 else
1173 major_dev = i;
1175 #ifdef CONFIG_PROC_FS
1176 proc_pccard = proc_mkdir("pccard", proc_bus);
1177 if (proc_pccard)
1178 create_proc_read_entry("drivers",0,proc_pccard,proc_read_drivers,NULL);
1179 #endif
1181 return 0;
1183 fs_initcall(init_pcmcia_bus); /* one level after subsys_initcall so that
1184 * pcmcia_socket_class is already registered */
1187 static void __exit exit_pcmcia_bus(void)
1189 class_interface_unregister(&pcmcia_bus_interface);
1191 #ifdef CONFIG_PROC_FS
1192 if (proc_pccard) {
1193 remove_proc_entry("drivers", proc_pccard);
1194 remove_proc_entry("pccard", proc_bus);
1196 #endif
1197 if (major_dev != -1)
1198 unregister_chrdev(major_dev, "pcmcia");
1200 bus_unregister(&pcmcia_bus_type);
1202 module_exit(exit_pcmcia_bus);
1206 /* helpers for backwards-compatible functions */
1208 static struct pcmcia_bus_socket * get_socket_info_by_nr(unsigned int nr)
1210 struct pcmcia_socket * s = pcmcia_get_socket_by_nr(nr);
1211 if (s && s->pcmcia)
1212 return s->pcmcia;
1213 else
1214 return NULL;
1217 /* backwards-compatible accessing of driver --- by name! */
1219 struct cmp_data {
1220 void *dev_info;
1221 struct pcmcia_driver *drv;
1224 static int cmp_drv_callback(struct device_driver *drv, void *data)
1226 struct cmp_data *cmp = data;
1227 if (strncmp((char *)cmp->dev_info, (char *)drv->name,
1228 DEV_NAME_LEN) == 0) {
1229 cmp->drv = container_of(drv, struct pcmcia_driver, drv);
1230 return -EINVAL;
1232 return 0;
1235 static struct pcmcia_driver * get_pcmcia_driver (dev_info_t *dev_info)
1237 int ret;
1238 struct cmp_data cmp = {
1239 .dev_info = dev_info,
1242 ret = bus_for_each_drv(&pcmcia_bus_type, NULL, &cmp, cmp_drv_callback);
1243 if (ret)
1244 return cmp.drv;
1245 return NULL;