Merge git://git.kernel.org/pub/scm/linux/kernel/git/wim/linux-2.6-watchdog
[deliverable/linux.git] / drivers / pcmcia / pcmcia_ioctl.c
CommitLineData
e7a480d2
DB
1/*
2 * pcmcia_ioctl.c -- ioctl interface for cardmgr and cardctl
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * The initial developer of the original code is David A. Hinds
9 * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
10 * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
11 *
12 * (C) 1999 David A. Hinds
13 * (C) 2003 - 2004 Dominik Brodowski
14 */
15
16/*
17 * This file will go away soon.
18 */
19
20
3b659fb8 21#include <linux/kernel.h>
e7a480d2 22#include <linux/module.h>
e7a480d2 23#include <linux/init.h>
e7a480d2 24#include <linux/major.h>
e7a480d2 25#include <linux/errno.h>
e7a480d2
DB
26#include <linux/ioctl.h>
27#include <linux/proc_fs.h>
28#include <linux/poll.h>
29#include <linux/pci.h>
e6be4a8c 30#include <linux/seq_file.h>
0bec0bba 31#include <linux/smp_lock.h>
e7a480d2 32#include <linux/workqueue.h>
e7a480d2 33
e7a480d2
DB
34#include <pcmcia/cs_types.h>
35#include <pcmcia/cs.h>
e7a480d2 36#include <pcmcia/cistpl.h>
4aeba013 37#include <pcmcia/cisreg.h>
e7a480d2
DB
38#include <pcmcia/ds.h>
39#include <pcmcia/ss.h>
40
41#include "cs_internal.h"
e7a480d2
DB
42
43static int major_dev = -1;
44
45
46/* Device user information */
47#define MAX_EVENTS 32
48#define USER_MAGIC 0x7ea4
49#define CHECK_USER(u) \
50 (((u) == NULL) || ((u)->user_magic != USER_MAGIC))
51
52typedef struct user_info_t {
53 u_int user_magic;
54 int event_head, event_tail;
55 event_t event[MAX_EVENTS];
56 struct user_info_t *next;
dc109497 57 struct pcmcia_socket *socket;
e7a480d2
DB
58} user_info_t;
59
60
855cdf13
DB
61static struct pcmcia_device *get_pcmcia_device(struct pcmcia_socket *s,
62 unsigned int function)
63{
64 struct pcmcia_device *p_dev = NULL;
65 unsigned long flags;
66
67 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
68 list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
69 if (p_dev->func == function) {
70 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
71 return pcmcia_get_dev(p_dev);
72 }
73 }
74 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
75 return NULL;
76}
e7a480d2 77
e7a480d2
DB
78/* backwards-compatible accessing of driver --- by name! */
79
855cdf13 80static struct pcmcia_driver *get_pcmcia_driver(dev_info_t *dev_info)
e7a480d2
DB
81{
82 struct device_driver *drv;
83 struct pcmcia_driver *p_drv;
84
85 drv = driver_find((char *) dev_info, &pcmcia_bus_type);
86 if (!drv)
87 return NULL;
88
89 p_drv = container_of(drv, struct pcmcia_driver, drv);
90
9fea84f4 91 return p_drv;
e7a480d2
DB
92}
93
94
95#ifdef CONFIG_PROC_FS
9fea84f4 96static struct proc_dir_entry *proc_pccard;
e7a480d2 97
e6be4a8c 98static int proc_read_drivers_callback(struct device_driver *driver, void *_m)
e7a480d2 99{
e6be4a8c 100 struct seq_file *m = _m;
e7a480d2
DB
101 struct pcmcia_driver *p_drv = container_of(driver,
102 struct pcmcia_driver, drv);
103
e6be4a8c 104 seq_printf(m, "%-24.24s 1 %d\n", p_drv->drv.name,
e7a480d2
DB
105#ifdef CONFIG_MODULE_UNLOAD
106 (p_drv->owner) ? module_refcount(p_drv->owner) : 1
107#else
108 1
109#endif
110 );
e7a480d2
DB
111 return 0;
112}
113
e6be4a8c 114static int pccard_drivers_proc_show(struct seq_file *m, void *v)
e7a480d2 115{
e6be4a8c
AD
116 return bus_for_each_drv(&pcmcia_bus_type, NULL,
117 m, proc_read_drivers_callback);
118}
e7a480d2 119
e6be4a8c
AD
120static int pccard_drivers_proc_open(struct inode *inode, struct file *file)
121{
122 return single_open(file, pccard_drivers_proc_show, NULL);
e7a480d2 123}
e6be4a8c
AD
124
125static const struct file_operations pccard_drivers_proc_fops = {
126 .owner = THIS_MODULE,
127 .open = pccard_drivers_proc_open,
128 .read = seq_read,
129 .llseek = seq_lseek,
130 .release = single_release,
131};
e7a480d2
DB
132#endif
133
c5023801
DB
134
135#ifdef CONFIG_PCMCIA_PROBE
136
137static int adjust_irq(struct pcmcia_socket *s, adjust_t *adj)
138{
139 int irq;
140 u32 mask;
141
142 irq = adj->resource.irq.IRQ;
143 if ((irq < 0) || (irq > 15))
69ba4433 144 return -EINVAL;
c5023801
DB
145
146 if (adj->Action != REMOVE_MANAGED_RESOURCE)
147 return 0;
148
149 mask = 1 << irq;
150
151 if (!(s->irq_mask & mask))
152 return 0;
153
154 s->irq_mask &= ~mask;
155
156 return 0;
157}
158
159#else
160
9fea84f4
DB
161static inline int adjust_irq(struct pcmcia_socket *s, adjust_t *adj)
162{
4c89e88b 163 return 0;
c5023801
DB
164}
165
166#endif
167
168static int pcmcia_adjust_resource_info(adjust_t *adj)
169{
170 struct pcmcia_socket *s;
de6405e9 171 int ret = -ENOSYS;
c5023801
DB
172 unsigned long flags;
173
174 down_read(&pcmcia_socket_list_rwsem);
175 list_for_each_entry(s, &pcmcia_socket_list, socket_list) {
176
177 if (adj->Resource == RES_IRQ)
178 ret = adjust_irq(s, adj);
179
180 else if (s->resource_ops->add_io) {
181 unsigned long begin, end;
182
183 /* you can't use the old interface if the new
184 * one was used before */
185 spin_lock_irqsave(&s->lock, flags);
186 if ((s->resource_setup_new) &&
187 !(s->resource_setup_old)) {
188 spin_unlock_irqrestore(&s->lock, flags);
189 continue;
190 } else if (!(s->resource_setup_old))
191 s->resource_setup_old = 1;
192 spin_unlock_irqrestore(&s->lock, flags);
193
194 switch (adj->Resource) {
195 case RES_MEMORY_RANGE:
196 begin = adj->resource.memory.Base;
197 end = adj->resource.memory.Base + adj->resource.memory.Size - 1;
198 if (s->resource_ops->add_mem)
9fea84f4 199 ret = s->resource_ops->add_mem(s, adj->Action, begin, end);
c5023801
DB
200 case RES_IO_RANGE:
201 begin = adj->resource.io.BasePort;
202 end = adj->resource.io.BasePort + adj->resource.io.NumPorts - 1;
203 if (s->resource_ops->add_io)
204 ret = s->resource_ops->add_io(s, adj->Action, begin, end);
205 }
206 if (!ret) {
207 /* as there's no way we know this is the
208 * last call to adjust_resource_info, we
209 * always need to assume this is the latest
210 * one... */
211 spin_lock_irqsave(&s->lock, flags);
212 s->resource_setup_done = 1;
213 spin_unlock_irqrestore(&s->lock, flags);
214 }
215 }
216 }
217 up_read(&pcmcia_socket_list_rwsem);
218
9fea84f4 219 return ret;
c5023801
DB
220}
221
d7b0364b
DB
222
223/** pcmcia_get_window
224 */
225static int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *wh_out,
226 window_handle_t wh, win_req_t *req)
227{
82f88e36 228 pccard_mem_map *win;
d7b0364b
DB
229 window_handle_t w;
230
231 wh--;
232 if (!s || !(s->state & SOCKET_PRESENT))
233 return -ENODEV;
234 if (wh >= MAX_WIN)
235 return -EINVAL;
236 for (w = wh; w < MAX_WIN; w++)
237 if (s->state & SOCKET_WIN_REQ(w))
238 break;
239 if (w == MAX_WIN)
240 return -EINVAL;
241 win = &s->win[w];
82f88e36
DB
242 req->Base = win->res->start;
243 req->Size = win->res->end - win->res->start + 1;
244 req->AccessSpeed = win->speed;
d7b0364b 245 req->Attributes = 0;
82f88e36 246 if (win->flags & MAP_ATTRIB)
d7b0364b 247 req->Attributes |= WIN_MEMORY_TYPE_AM;
82f88e36 248 if (win->flags & MAP_ACTIVE)
d7b0364b 249 req->Attributes |= WIN_ENABLE;
82f88e36 250 if (win->flags & MAP_16BIT)
d7b0364b 251 req->Attributes |= WIN_DATA_WIDTH_16;
82f88e36 252 if (win->flags & MAP_USE_WAIT)
d7b0364b
DB
253 req->Attributes |= WIN_USE_WAIT;
254
255 *wh_out = w + 1;
256 return 0;
257} /* pcmcia_get_window */
258
259
260/** pcmcia_get_mem_page
261 *
262 * Change the card address of an already open memory window.
263 */
264static int pcmcia_get_mem_page(struct pcmcia_socket *skt, window_handle_t wh,
265 memreq_t *req)
266{
267 wh--;
268 if (wh >= MAX_WIN)
269 return -EINVAL;
270
271 req->Page = 0;
82f88e36 272 req->CardOffset = skt->win[wh].card_start;
d7b0364b
DB
273 return 0;
274} /* pcmcia_get_mem_page */
275
276
4aeba013
DB
277/** pccard_get_status
278 *
279 * Get the current socket state bits. We don't support the latched
280 * SocketState yet: I haven't seen any point for it.
281 */
282
283static int pccard_get_status(struct pcmcia_socket *s,
284 struct pcmcia_device *p_dev,
285 cs_status_t *status)
286{
287 config_t *c;
288 int val;
289
290 s->ops->get_status(s, &val);
291 status->CardState = status->SocketState = 0;
292 status->CardState |= (val & SS_DETECT) ? CS_EVENT_CARD_DETECT : 0;
293 status->CardState |= (val & SS_CARDBUS) ? CS_EVENT_CB_DETECT : 0;
294 status->CardState |= (val & SS_3VCARD) ? CS_EVENT_3VCARD : 0;
295 status->CardState |= (val & SS_XVCARD) ? CS_EVENT_XVCARD : 0;
296 if (s->state & SOCKET_SUSPEND)
297 status->CardState |= CS_EVENT_PM_SUSPEND;
298 if (!(s->state & SOCKET_PRESENT))
3939c1ef 299 return -ENODEV;
4aeba013
DB
300
301 c = (p_dev) ? p_dev->function_config : NULL;
302
303 if ((c != NULL) && (c->state & CONFIG_LOCKED) &&
304 (c->IntType & (INT_MEMORY_AND_IO | INT_ZOOMED_VIDEO))) {
305 u_char reg;
306 if (c->CardValues & PRESENT_PIN_REPLACE) {
307 pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_PRR)>>1, 1, &reg);
308 status->CardState |=
309 (reg & PRR_WP_STATUS) ? CS_EVENT_WRITE_PROTECT : 0;
310 status->CardState |=
311 (reg & PRR_READY_STATUS) ? CS_EVENT_READY_CHANGE : 0;
312 status->CardState |=
313 (reg & PRR_BVD2_STATUS) ? CS_EVENT_BATTERY_LOW : 0;
314 status->CardState |=
315 (reg & PRR_BVD1_STATUS) ? CS_EVENT_BATTERY_DEAD : 0;
316 } else {
317 /* No PRR? Then assume we're always ready */
318 status->CardState |= CS_EVENT_READY_CHANGE;
319 }
320 if (c->CardValues & PRESENT_EXT_STATUS) {
321 pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_ESR)>>1, 1, &reg);
322 status->CardState |=
323 (reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0;
324 }
4c89e88b 325 return 0;
4aeba013
DB
326 }
327 status->CardState |=
328 (val & SS_WRPROT) ? CS_EVENT_WRITE_PROTECT : 0;
329 status->CardState |=
330 (val & SS_BATDEAD) ? CS_EVENT_BATTERY_DEAD : 0;
331 status->CardState |=
332 (val & SS_BATWARN) ? CS_EVENT_BATTERY_LOW : 0;
333 status->CardState |=
334 (val & SS_READY) ? CS_EVENT_READY_CHANGE : 0;
4c89e88b 335 return 0;
4aeba013 336} /* pccard_get_status */
c5023801 337
a0779327 338static int pccard_get_configuration_info(struct pcmcia_socket *s,
64f34642
DB
339 struct pcmcia_device *p_dev,
340 config_info_t *config)
341{
342 config_t *c;
343
344 if (!(s->state & SOCKET_PRESENT))
3939c1ef 345 return -ENODEV;
64f34642
DB
346
347
348#ifdef CONFIG_CARDBUS
349 if (s->state & SOCKET_CARDBUS) {
350 memset(config, 0, sizeof(config_info_t));
351 config->Vcc = s->socket.Vcc;
352 config->Vpp1 = config->Vpp2 = s->socket.Vpp;
353 config->Option = s->cb_dev->subordinate->number;
354 if (s->state & SOCKET_CARDBUS_CONFIG) {
355 config->Attributes = CONF_VALID_CLIENT;
356 config->IntType = INT_CARDBUS;
357 config->AssignedIRQ = s->irq.AssignedIRQ;
358 if (config->AssignedIRQ)
359 config->Attributes |= CONF_ENABLE_IRQ;
360 if (s->io[0].res) {
361 config->BasePort1 = s->io[0].res->start;
362 config->NumPorts1 = s->io[0].res->end -
363 config->BasePort1 + 1;
364 }
365 }
4c89e88b 366 return 0;
64f34642
DB
367 }
368#endif
369
370 if (p_dev) {
371 c = p_dev->function_config;
372 config->Function = p_dev->func;
373 } else {
374 c = NULL;
375 config->Function = 0;
376 }
377
378 if ((c == NULL) || !(c->state & CONFIG_LOCKED)) {
379 config->Attributes = 0;
380 config->Vcc = s->socket.Vcc;
381 config->Vpp1 = config->Vpp2 = s->socket.Vpp;
4c89e88b 382 return 0;
64f34642
DB
383 }
384
385 config->Attributes = c->Attributes | CONF_VALID_CLIENT;
386 config->Vcc = s->socket.Vcc;
387 config->Vpp1 = config->Vpp2 = s->socket.Vpp;
388 config->IntType = c->IntType;
389 config->ConfigBase = c->ConfigBase;
390 config->Status = c->Status;
391 config->Pin = c->Pin;
392 config->Copy = c->Copy;
393 config->Option = c->Option;
394 config->ExtStatus = c->ExtStatus;
395 config->Present = config->CardValues = c->CardValues;
396 config->IRQAttributes = c->irq.Attributes;
397 config->AssignedIRQ = s->irq.AssignedIRQ;
398 config->BasePort1 = c->io.BasePort1;
399 config->NumPorts1 = c->io.NumPorts1;
400 config->Attributes1 = c->io.Attributes1;
401 config->BasePort2 = c->io.BasePort2;
402 config->NumPorts2 = c->io.NumPorts2;
403 config->Attributes2 = c->io.Attributes2;
404 config->IOAddrLines = c->io.IOAddrLines;
405
4c89e88b 406 return 0;
64f34642
DB
407} /* pccard_get_configuration_info */
408
409
e7a480d2
DB
410/*======================================================================
411
412 These manage a ring buffer of events pending for one user process
413
414======================================================================*/
415
416
417static int queue_empty(user_info_t *user)
418{
419 return (user->event_head == user->event_tail);
420}
421
422static event_t get_queued_event(user_info_t *user)
423{
424 user->event_tail = (user->event_tail+1) % MAX_EVENTS;
425 return user->event[user->event_tail];
426}
427
428static void queue_event(user_info_t *user, event_t event)
429{
430 user->event_head = (user->event_head+1) % MAX_EVENTS;
431 if (user->event_head == user->event_tail)
432 user->event_tail = (user->event_tail+1) % MAX_EVENTS;
433 user->event[user->event_head] = event;
434}
435
dc109497 436void handle_event(struct pcmcia_socket *s, event_t event)
e7a480d2
DB
437{
438 user_info_t *user;
439 for (user = s->user; user; user = user->next)
440 queue_event(user, event);
441 wake_up_interruptible(&s->queue);
442}
443
444
445/*======================================================================
446
447 bind_request() and bind_device() are merged by now. Register_client()
448 is called right at the end of bind_request(), during the driver's
449 ->attach() call. Individual descriptions:
450
451 bind_request() connects a socket to a particular client driver.
452 It looks up the specified device ID in the list of registered
453 drivers, binds it to the socket, and tries to create an instance
454 of the device. unbind_request() deletes a driver instance.
455
456 Bind_device() associates a device driver with a particular socket.
457 It is normally called by Driver Services after it has identified
458 a newly inserted card. An instance of that driver will then be
459 eligible to register as a client of this socket.
460
461 Register_client() uses the dev_info_t handle to match the
462 caller with a socket. The driver must have already been bound
463 to a socket with bind_device() -- in fact, bind_device()
464 allocates the client structure that will be used.
465
466======================================================================*/
467
dc109497 468static int bind_request(struct pcmcia_socket *s, bind_info_t *bind_info)
e7a480d2
DB
469{
470 struct pcmcia_driver *p_drv;
471 struct pcmcia_device *p_dev;
472 int ret = 0;
473 unsigned long flags;
474
dc109497 475 s = pcmcia_get_socket(s);
e7a480d2
DB
476 if (!s)
477 return -EINVAL;
478
d50dbec3 479 pr_debug("bind_request(%d, '%s')\n", s->sock,
e7a480d2
DB
480 (char *)bind_info->dev_info);
481
482 p_drv = get_pcmcia_driver(&bind_info->dev_info);
483 if (!p_drv) {
484 ret = -EINVAL;
485 goto err_put;
486 }
487
488 if (!try_module_get(p_drv->owner)) {
489 ret = -EINVAL;
490 goto err_put_driver;
491 }
492
493 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
9fea84f4 494 list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
e7a480d2
DB
495 if (p_dev->func == bind_info->function) {
496 if ((p_dev->dev.driver == &p_drv->drv)) {
497 if (p_dev->cardmgr) {
498 /* if there's already a device
499 * registered, and it was registered
500 * by userspace before, we need to
501 * return the "instance". */
502 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
fd238232 503 bind_info->instance = p_dev;
e7a480d2
DB
504 ret = -EBUSY;
505 goto err_put_module;
506 } else {
507 /* the correct driver managed to bind
508 * itself magically to the correct
509 * device. */
510 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
511 p_dev->cardmgr = p_drv;
512 ret = 0;
513 goto err_put_module;
514 }
515 } else if (!p_dev->dev.driver) {
516 /* there's already a device available where
517 * no device has been bound to yet. So we don't
518 * need to register a device! */
519 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
520 goto rescan;
521 }
522 }
523 }
524 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
525
526 p_dev = pcmcia_device_add(s, bind_info->function);
527 if (!p_dev) {
528 ret = -EIO;
529 goto err_put_module;
530 }
531
532rescan:
533 p_dev->cardmgr = p_drv;
534
535 /* if a driver is already running, we can abort */
536 if (p_dev->dev.driver)
537 goto err_put_module;
538
539 /*
540 * Prevent this racing with a card insertion.
541 */
7fe908dd 542 mutex_lock(&s->skt_mutex);
4deb7c1e 543 ret = bus_rescan_devices(&pcmcia_bus_type);
7fe908dd 544 mutex_unlock(&s->skt_mutex);
4deb7c1e
JG
545 if (ret)
546 goto err_put_module;
e7a480d2
DB
547
548 /* check whether the driver indeed matched. I don't care if this
549 * is racy or not, because it can only happen on cardmgr access
550 * paths...
551 */
552 if (!(p_dev->dev.driver == &p_drv->drv))
553 p_dev->cardmgr = NULL;
554
555 err_put_module:
556 module_put(p_drv->owner);
557 err_put_driver:
558 put_driver(&p_drv->drv);
559 err_put:
dc109497 560 pcmcia_put_socket(s);
e7a480d2 561
9fea84f4 562 return ret;
e7a480d2
DB
563} /* bind_request */
564
33519ddd
DB
565#ifdef CONFIG_CARDBUS
566
567static struct pci_bus *pcmcia_lookup_bus(struct pcmcia_socket *s)
568{
569 if (!s || !(s->state & SOCKET_CARDBUS))
570 return NULL;
e7a480d2 571
33519ddd
DB
572 return s->cb_dev->subordinate;
573}
574#endif
e7a480d2 575
dc109497 576static int get_device_info(struct pcmcia_socket *s, bind_info_t *bind_info, int first)
e7a480d2
DB
577{
578 dev_node_t *node;
579 struct pcmcia_device *p_dev;
e2d40963 580 struct pcmcia_driver *p_drv;
e7a480d2
DB
581 unsigned long flags;
582 int ret = 0;
583
584#ifdef CONFIG_CARDBUS
585 /*
586 * Some unbelievably ugly code to associate the PCI cardbus
587 * device and its driver with the PCMCIA "bind" information.
588 */
589 {
590 struct pci_bus *bus;
591
dc109497 592 bus = pcmcia_lookup_bus(s);
e7a480d2
DB
593 if (bus) {
594 struct list_head *list;
595 struct pci_dev *dev = NULL;
596
597 list = bus->devices.next;
598 while (list != &bus->devices) {
599 struct pci_dev *pdev = pci_dev_b(list);
600 list = list->next;
601
602 if (first) {
603 dev = pdev;
604 break;
605 }
606
607 /* Try to handle "next" here some way? */
608 }
609 if (dev && dev->driver) {
610 strlcpy(bind_info->name, dev->driver->name, DEV_NAME_LEN);
611 bind_info->major = 0;
612 bind_info->minor = 0;
613 bind_info->next = NULL;
614 return 0;
615 }
616 }
617 }
618#endif
619
620 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
621 list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
622 if (p_dev->func == bind_info->function) {
623 p_dev = pcmcia_get_dev(p_dev);
624 if (!p_dev)
625 continue;
626 goto found;
627 }
628 }
629 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
630 return -ENODEV;
631
632 found:
633 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
634
e2d40963
DB
635 p_drv = to_pcmcia_drv(p_dev->dev.driver);
636 if (p_drv && !p_dev->_locked) {
e7a480d2
DB
637 ret = -EAGAIN;
638 goto err_put;
639 }
640
641 if (first)
fd238232 642 node = p_dev->dev_node;
e7a480d2 643 else
fd238232 644 for (node = p_dev->dev_node; node; node = node->next)
e7a480d2
DB
645 if (node == bind_info->next)
646 break;
647 if (!node) {
648 ret = -ENODEV;
649 goto err_put;
650 }
651
652 strlcpy(bind_info->name, node->dev_name, DEV_NAME_LEN);
653 bind_info->major = node->major;
654 bind_info->minor = node->minor;
655 bind_info->next = node->next;
656
657 err_put:
658 pcmcia_put_dev(p_dev);
9fea84f4 659 return ret;
e7a480d2
DB
660} /* get_device_info */
661
662
663static int ds_open(struct inode *inode, struct file *file)
664{
665 socket_t i = iminor(inode);
dc109497 666 struct pcmcia_socket *s;
e7a480d2 667 user_info_t *user;
9fea84f4 668 static int warning_printed;
0bec0bba 669 int ret = 0;
e7a480d2 670
d50dbec3 671 pr_debug("ds_open(socket %d)\n", i);
e7a480d2 672
0bec0bba 673 lock_kernel();
dc109497 674 s = pcmcia_get_socket_by_nr(i);
0bec0bba
JC
675 if (!s) {
676 ret = -ENODEV;
677 goto out;
678 }
dc109497 679 s = pcmcia_get_socket(s);
0bec0bba
JC
680 if (!s) {
681 ret = -ENODEV;
682 goto out;
683 }
e7a480d2
DB
684
685 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
b5e43913 686 if (s->pcmcia_state.busy) {
dc109497 687 pcmcia_put_socket(s);
0bec0bba
JC
688 ret = -EBUSY;
689 goto out;
e7a480d2
DB
690 }
691 else
b5e43913 692 s->pcmcia_state.busy = 1;
e7a480d2
DB
693 }
694
695 user = kmalloc(sizeof(user_info_t), GFP_KERNEL);
696 if (!user) {
dc109497 697 pcmcia_put_socket(s);
0bec0bba
JC
698 ret = -ENOMEM;
699 goto out;
e7a480d2
DB
700 }
701 user->event_tail = user->event_head = 0;
702 user->next = s->user;
703 user->user_magic = USER_MAGIC;
704 user->socket = s;
705 s->user = user;
706 file->private_data = user;
707
c352ec8a
DB
708 if (!warning_printed) {
709 printk(KERN_INFO "pcmcia: Detected deprecated PCMCIA ioctl "
73d58588 710 "usage from process: %s.\n", current->comm);
c352ec8a
DB
711 printk(KERN_INFO "pcmcia: This interface will soon be removed from "
712 "the kernel; please expect breakage unless you upgrade "
713 "to new tools.\n");
714 printk(KERN_INFO "pcmcia: see http://www.kernel.org/pub/linux/"
715 "utils/kernel/pcmcia/pcmcia.html for details.\n");
716 warning_printed = 1;
717 }
718
b5e43913 719 if (s->pcmcia_state.present)
e7a480d2 720 queue_event(user, CS_EVENT_CARD_INSERTION);
0bec0bba
JC
721out:
722 unlock_kernel();
723 return ret;
e7a480d2
DB
724} /* ds_open */
725
726/*====================================================================*/
727
728static int ds_release(struct inode *inode, struct file *file)
729{
dc109497 730 struct pcmcia_socket *s;
e7a480d2
DB
731 user_info_t *user, **link;
732
d50dbec3 733 pr_debug("ds_release(socket %d)\n", iminor(inode));
e7a480d2
DB
734
735 user = file->private_data;
736 if (CHECK_USER(user))
737 goto out;
738
739 s = user->socket;
740
741 /* Unlink user data structure */
9fea84f4 742 if ((file->f_flags & O_ACCMODE) != O_RDONLY)
b5e43913 743 s->pcmcia_state.busy = 0;
9fea84f4 744
e7a480d2
DB
745 file->private_data = NULL;
746 for (link = &s->user; *link; link = &(*link)->next)
9fea84f4
DB
747 if (*link == user)
748 break;
e7a480d2
DB
749 if (link == NULL)
750 goto out;
751 *link = user->next;
752 user->user_magic = 0;
753 kfree(user);
dc109497 754 pcmcia_put_socket(s);
e7a480d2
DB
755out:
756 return 0;
757} /* ds_release */
758
759/*====================================================================*/
760
761static ssize_t ds_read(struct file *file, char __user *buf,
762 size_t count, loff_t *ppos)
763{
dc109497 764 struct pcmcia_socket *s;
e7a480d2
DB
765 user_info_t *user;
766 int ret;
767
d50dbec3 768 pr_debug("ds_read(socket %d)\n", iminor(file->f_path.dentry->d_inode));
e7a480d2
DB
769
770 if (count < 4)
771 return -EINVAL;
772
773 user = file->private_data;
774 if (CHECK_USER(user))
775 return -EIO;
776
777 s = user->socket;
b5e43913 778 if (s->pcmcia_state.dead)
9fea84f4 779 return -EIO;
e7a480d2
DB
780
781 ret = wait_event_interruptible(s->queue, !queue_empty(user));
782 if (ret == 0)
783 ret = put_user(get_queued_event(user), (int __user *)buf) ? -EFAULT : 4;
784
785 return ret;
786} /* ds_read */
787
788/*====================================================================*/
789
790static ssize_t ds_write(struct file *file, const char __user *buf,
791 size_t count, loff_t *ppos)
792{
d50dbec3 793 pr_debug("ds_write(socket %d)\n", iminor(file->f_path.dentry->d_inode));
e7a480d2
DB
794
795 if (count != 4)
796 return -EINVAL;
797 if ((file->f_flags & O_ACCMODE) == O_RDONLY)
798 return -EBADF;
799
800 return -EIO;
801} /* ds_write */
802
803/*====================================================================*/
804
805/* No kernel lock - fine */
806static u_int ds_poll(struct file *file, poll_table *wait)
807{
dc109497 808 struct pcmcia_socket *s;
e7a480d2
DB
809 user_info_t *user;
810
d50dbec3 811 pr_debug("ds_poll(socket %d)\n", iminor(file->f_path.dentry->d_inode));
e7a480d2
DB
812
813 user = file->private_data;
814 if (CHECK_USER(user))
815 return POLLERR;
816 s = user->socket;
817 /*
818 * We don't check for a dead socket here since that
819 * will send cardmgr into an endless spin.
820 */
821 poll_wait(file, &s->queue, wait);
822 if (!queue_empty(user))
823 return POLLIN | POLLRDNORM;
824 return 0;
825} /* ds_poll */
826
827/*====================================================================*/
828
9fea84f4 829static int ds_ioctl(struct inode *inode, struct file *file,
e7a480d2
DB
830 u_int cmd, u_long arg)
831{
dc109497 832 struct pcmcia_socket *s;
e7a480d2
DB
833 void __user *uarg = (char __user *)arg;
834 u_int size;
835 int ret, err;
836 ds_ioctl_arg_t *buf;
837 user_info_t *user;
838
d50dbec3 839 pr_debug("ds_ioctl(socket %d, %#x, %#lx)\n", iminor(inode), cmd, arg);
e7a480d2
DB
840
841 user = file->private_data;
842 if (CHECK_USER(user))
843 return -EIO;
844
845 s = user->socket;
b5e43913 846 if (s->pcmcia_state.dead)
9fea84f4 847 return -EIO;
e7a480d2
DB
848
849 size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
9fea84f4
DB
850 if (size > sizeof(ds_ioctl_arg_t))
851 return -EINVAL;
e7a480d2
DB
852
853 /* Permission check */
854 if (!(cmd & IOC_OUT) && !capable(CAP_SYS_ADMIN))
855 return -EPERM;
856
857 if (cmd & IOC_IN) {
858 if (!access_ok(VERIFY_READ, uarg, size)) {
d50dbec3 859 pr_debug("ds_ioctl(): verify_read = %d\n", -EFAULT);
e7a480d2
DB
860 return -EFAULT;
861 }
862 }
863 if (cmd & IOC_OUT) {
864 if (!access_ok(VERIFY_WRITE, uarg, size)) {
d50dbec3 865 pr_debug("ds_ioctl(): verify_write = %d\n", -EFAULT);
e7a480d2
DB
866 return -EFAULT;
867 }
868 }
869 buf = kmalloc(sizeof(ds_ioctl_arg_t), GFP_KERNEL);
870 if (!buf)
871 return -ENOMEM;
872
873 err = ret = 0;
874
9374074f
DB
875 if (cmd & IOC_IN) {
876 if (__copy_from_user((char *)buf, uarg, size)) {
877 err = -EFAULT;
878 goto free_out;
879 }
880 }
e7a480d2
DB
881
882 switch (cmd) {
883 case DS_ADJUST_RESOURCE_INFO:
884 ret = pcmcia_adjust_resource_info(&buf->adjust);
885 break;
e7a480d2
DB
886 case DS_GET_CONFIGURATION_INFO:
887 if (buf->config.Function &&
dc109497 888 (buf->config.Function >= s->functions))
926c5402 889 ret = -EINVAL;
855cdf13
DB
890 else {
891 struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->config.Function);
f47ad214
DR
892 ret = pccard_get_configuration_info(s, p_dev, &buf->config);
893 pcmcia_put_dev(p_dev);
855cdf13 894 }
e7a480d2
DB
895 break;
896 case DS_GET_FIRST_TUPLE:
7fe908dd 897 mutex_lock(&s->skt_mutex);
dc109497 898 pcmcia_validate_mem(s);
7fe908dd 899 mutex_unlock(&s->skt_mutex);
dc109497 900 ret = pccard_get_first_tuple(s, BIND_FN_ALL, &buf->tuple);
e7a480d2
DB
901 break;
902 case DS_GET_NEXT_TUPLE:
dc109497 903 ret = pccard_get_next_tuple(s, BIND_FN_ALL, &buf->tuple);
e7a480d2
DB
904 break;
905 case DS_GET_TUPLE_DATA:
906 buf->tuple.TupleData = buf->tuple_parse.data;
907 buf->tuple.TupleDataMax = sizeof(buf->tuple_parse.data);
dc109497 908 ret = pccard_get_tuple_data(s, &buf->tuple);
e7a480d2
DB
909 break;
910 case DS_PARSE_TUPLE:
911 buf->tuple.TupleData = buf->tuple_parse.data;
2f3061eb 912 ret = pcmcia_parse_tuple(&buf->tuple, &buf->tuple_parse.parse);
e7a480d2
DB
913 break;
914 case DS_RESET_CARD:
994917f8 915 ret = pcmcia_reset_card(s);
e7a480d2
DB
916 break;
917 case DS_GET_STATUS:
855cdf13
DB
918 if (buf->status.Function &&
919 (buf->status.Function >= s->functions))
926c5402 920 ret = -EINVAL;
855cdf13
DB
921 else {
922 struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->status.Function);
f47ad214
DR
923 ret = pccard_get_status(s, p_dev, &buf->status);
924 pcmcia_put_dev(p_dev);
855cdf13
DB
925 }
926 break;
e7a480d2 927 case DS_VALIDATE_CIS:
7fe908dd 928 mutex_lock(&s->skt_mutex);
dc109497 929 pcmcia_validate_mem(s);
7fe908dd 930 mutex_unlock(&s->skt_mutex);
84897fc0 931 ret = pccard_validate_cis(s, &buf->cisinfo.Chains);
e7a480d2
DB
932 break;
933 case DS_SUSPEND_CARD:
dc109497 934 ret = pcmcia_suspend_card(s);
e7a480d2
DB
935 break;
936 case DS_RESUME_CARD:
dc109497 937 ret = pcmcia_resume_card(s);
e7a480d2
DB
938 break;
939 case DS_EJECT_CARD:
dc109497 940 err = pcmcia_eject_card(s);
e7a480d2
DB
941 break;
942 case DS_INSERT_CARD:
dc109497 943 err = pcmcia_insert_card(s);
e7a480d2
DB
944 break;
945 case DS_ACCESS_CONFIGURATION_REGISTER:
946 if ((buf->conf_reg.Action == CS_WRITE) && !capable(CAP_SYS_ADMIN)) {
947 err = -EPERM;
948 goto free_out;
949 }
855cdf13 950
926c5402 951 ret = -EINVAL;
855cdf13
DB
952
953 if (!(buf->conf_reg.Function &&
954 (buf->conf_reg.Function >= s->functions))) {
955 struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->conf_reg.Function);
73d58588 956 if (p_dev) {
855cdf13 957 ret = pcmcia_access_configuration_register(p_dev, &buf->conf_reg);
73d58588
BH
958 pcmcia_put_dev(p_dev);
959 }
855cdf13 960 }
e7a480d2
DB
961 break;
962 case DS_GET_FIRST_REGION:
963 case DS_GET_NEXT_REGION:
964 case DS_BIND_MTD:
965 if (!capable(CAP_SYS_ADMIN)) {
966 err = -EPERM;
967 goto free_out;
968 } else {
a9c56953
MK
969 printk_once(KERN_WARNING
970 "2.6. kernels use pcmciamtd instead of memory_cs.c and do not require special\n");
971 printk_once(KERN_WARNING "MTD handling any more.\n");
e7a480d2
DB
972 }
973 err = -EINVAL;
974 goto free_out;
975 break;
976 case DS_GET_FIRST_WINDOW:
0bdf9b3d 977 ret = pcmcia_get_window(s, &buf->win_info.handle, 1,
e7a480d2
DB
978 &buf->win_info.window);
979 break;
980 case DS_GET_NEXT_WINDOW:
dc109497 981 ret = pcmcia_get_window(s, &buf->win_info.handle,
0bdf9b3d 982 buf->win_info.handle + 1, &buf->win_info.window);
e7a480d2
DB
983 break;
984 case DS_GET_MEM_PAGE:
16456eba 985 ret = pcmcia_get_mem_page(s, buf->win_info.handle,
e7a480d2
DB
986 &buf->win_info.map);
987 break;
988 case DS_REPLACE_CIS:
53efec95 989 ret = pcmcia_replace_cis(s, buf->cisdump.Data, buf->cisdump.Length);
e7a480d2
DB
990 break;
991 case DS_BIND_REQUEST:
992 if (!capable(CAP_SYS_ADMIN)) {
993 err = -EPERM;
994 goto free_out;
995 }
996 err = bind_request(s, &buf->bind_info);
997 break;
998 case DS_GET_DEVICE_INFO:
999 err = get_device_info(s, &buf->bind_info, 1);
1000 break;
1001 case DS_GET_NEXT_DEVICE:
1002 err = get_device_info(s, &buf->bind_info, 0);
1003 break;
1004 case DS_UNBIND_REQUEST:
1005 err = 0;
1006 break;
1007 default:
1008 err = -EINVAL;
1009 }
1010
4c89e88b 1011 if ((err == 0) && (ret != 0)) {
d50dbec3 1012 pr_debug("ds_ioctl: ret = %d\n", ret);
e7a480d2 1013 switch (ret) {
610e2374
DB
1014 case -ENODEV:
1015 case -EINVAL:
1016 case -EBUSY:
1017 case -ENOSYS:
1018 err = ret;
1019 break;
610e2374 1020 case -ENOMEM:
e7a480d2 1021 err = -ENOSPC; break;
635d19be 1022 case -ENOSPC:
e7a480d2 1023 err = -ENODATA; break;
e7a480d2
DB
1024 default:
1025 err = -EIO; break;
1026 }
1027 }
1028
1029 if (cmd & IOC_OUT) {
9fea84f4
DB
1030 if (__copy_to_user(uarg, (char *)buf, size))
1031 err = -EFAULT;
e7a480d2
DB
1032 }
1033
1034free_out:
1035 kfree(buf);
1036 return err;
1037} /* ds_ioctl */
1038
1039/*====================================================================*/
1040
d54b1fdb 1041static const struct file_operations ds_fops = {
e7a480d2
DB
1042 .owner = THIS_MODULE,
1043 .open = ds_open,
1044 .release = ds_release,
1045 .ioctl = ds_ioctl,
1046 .read = ds_read,
1047 .write = ds_write,
1048 .poll = ds_poll,
1049};
1050
9fea84f4
DB
1051void __init pcmcia_setup_ioctl(void)
1052{
e7a480d2
DB
1053 int i;
1054
1055 /* Set up character device for user mode clients */
1056 i = register_chrdev(0, "pcmcia", &ds_fops);
1a8ceafc 1057 if (i < 0)
e7a480d2 1058 printk(KERN_NOTICE "unable to find a free device # for "
1a8ceafc 1059 "Driver Services (error=%d)\n", i);
e7a480d2
DB
1060 else
1061 major_dev = i;
1062
1063#ifdef CONFIG_PROC_FS
97094dcf 1064 proc_pccard = proc_mkdir("bus/pccard", NULL);
e7a480d2 1065 if (proc_pccard)
e6be4a8c 1066 proc_create("drivers", 0, proc_pccard, &pccard_drivers_proc_fops);
e7a480d2
DB
1067#endif
1068}
1069
1070
9fea84f4
DB
1071void __exit pcmcia_cleanup_ioctl(void)
1072{
e7a480d2
DB
1073#ifdef CONFIG_PROC_FS
1074 if (proc_pccard) {
1075 remove_proc_entry("drivers", proc_pccard);
97094dcf 1076 remove_proc_entry("bus/pccard", NULL);
e7a480d2
DB
1077 }
1078#endif
1079 if (major_dev != -1)
1080 unregister_chrdev(major_dev, "pcmcia");
1081}
This page took 1.069926 seconds and 5 git commands to generate.