]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/pcmcia/pcmcia_ioctl.c
Linux 2.6.35-rc6
[mirror_ubuntu-artful-kernel.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>
5a0e3ad6 30#include <linux/slab.h>
e6be4a8c 31#include <linux/seq_file.h>
0bec0bba 32#include <linux/smp_lock.h>
e7a480d2 33#include <linux/workqueue.h>
e7a480d2 34
e7a480d2
DB
35#include <pcmcia/cs_types.h>
36#include <pcmcia/cs.h>
e7a480d2 37#include <pcmcia/cistpl.h>
4aeba013 38#include <pcmcia/cisreg.h>
e7a480d2
DB
39#include <pcmcia/ds.h>
40#include <pcmcia/ss.h>
41
42#include "cs_internal.h"
e7a480d2
DB
43
44static int major_dev = -1;
45
46
47/* Device user information */
48#define MAX_EVENTS 32
49#define USER_MAGIC 0x7ea4
50#define CHECK_USER(u) \
51 (((u) == NULL) || ((u)->user_magic != USER_MAGIC))
52
53typedef struct user_info_t {
54 u_int user_magic;
55 int event_head, event_tail;
56 event_t event[MAX_EVENTS];
57 struct user_info_t *next;
dc109497 58 struct pcmcia_socket *socket;
e7a480d2
DB
59} user_info_t;
60
61
855cdf13
DB
62static struct pcmcia_device *get_pcmcia_device(struct pcmcia_socket *s,
63 unsigned int function)
64{
65 struct pcmcia_device *p_dev = NULL;
855cdf13 66
00ce99ff 67 mutex_lock(&s->ops_mutex);
855cdf13
DB
68 list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
69 if (p_dev->func == function) {
00ce99ff 70 mutex_unlock(&s->ops_mutex);
855cdf13
DB
71 return pcmcia_get_dev(p_dev);
72 }
73 }
00ce99ff 74 mutex_unlock(&s->ops_mutex);
855cdf13
DB
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
173 down_read(&pcmcia_socket_list_rwsem);
174 list_for_each_entry(s, &pcmcia_socket_list, socket_list) {
175
176 if (adj->Resource == RES_IRQ)
177 ret = adjust_irq(s, adj);
178
179 else if (s->resource_ops->add_io) {
180 unsigned long begin, end;
181
182 /* you can't use the old interface if the new
183 * one was used before */
00ce99ff 184 mutex_lock(&s->ops_mutex);
c5023801
DB
185 if ((s->resource_setup_new) &&
186 !(s->resource_setup_old)) {
00ce99ff 187 mutex_unlock(&s->ops_mutex);
c5023801
DB
188 continue;
189 } else if (!(s->resource_setup_old))
190 s->resource_setup_old = 1;
c5023801
DB
191
192 switch (adj->Resource) {
193 case RES_MEMORY_RANGE:
194 begin = adj->resource.memory.Base;
195 end = adj->resource.memory.Base + adj->resource.memory.Size - 1;
196 if (s->resource_ops->add_mem)
9fea84f4 197 ret = s->resource_ops->add_mem(s, adj->Action, begin, end);
c5023801
DB
198 case RES_IO_RANGE:
199 begin = adj->resource.io.BasePort;
200 end = adj->resource.io.BasePort + adj->resource.io.NumPorts - 1;
201 if (s->resource_ops->add_io)
202 ret = s->resource_ops->add_io(s, adj->Action, begin, end);
203 }
204 if (!ret) {
205 /* as there's no way we know this is the
206 * last call to adjust_resource_info, we
207 * always need to assume this is the latest
208 * one... */
c5023801 209 s->resource_setup_done = 1;
c5023801 210 }
cfe5d809 211 mutex_unlock(&s->ops_mutex);
c5023801
DB
212 }
213 }
214 up_read(&pcmcia_socket_list_rwsem);
215
9fea84f4 216 return ret;
c5023801
DB
217}
218
d7b0364b
DB
219
220/** pcmcia_get_window
221 */
222static int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *wh_out,
223 window_handle_t wh, win_req_t *req)
224{
82f88e36 225 pccard_mem_map *win;
d7b0364b
DB
226 window_handle_t w;
227
228 wh--;
229 if (!s || !(s->state & SOCKET_PRESENT))
230 return -ENODEV;
231 if (wh >= MAX_WIN)
232 return -EINVAL;
233 for (w = wh; w < MAX_WIN; w++)
234 if (s->state & SOCKET_WIN_REQ(w))
235 break;
236 if (w == MAX_WIN)
237 return -EINVAL;
238 win = &s->win[w];
82f88e36
DB
239 req->Base = win->res->start;
240 req->Size = win->res->end - win->res->start + 1;
241 req->AccessSpeed = win->speed;
d7b0364b 242 req->Attributes = 0;
82f88e36 243 if (win->flags & MAP_ATTRIB)
d7b0364b 244 req->Attributes |= WIN_MEMORY_TYPE_AM;
82f88e36 245 if (win->flags & MAP_ACTIVE)
d7b0364b 246 req->Attributes |= WIN_ENABLE;
82f88e36 247 if (win->flags & MAP_16BIT)
d7b0364b 248 req->Attributes |= WIN_DATA_WIDTH_16;
82f88e36 249 if (win->flags & MAP_USE_WAIT)
d7b0364b
DB
250 req->Attributes |= WIN_USE_WAIT;
251
252 *wh_out = w + 1;
253 return 0;
254} /* pcmcia_get_window */
255
256
257/** pcmcia_get_mem_page
258 *
259 * Change the card address of an already open memory window.
260 */
261static int pcmcia_get_mem_page(struct pcmcia_socket *skt, window_handle_t wh,
262 memreq_t *req)
263{
264 wh--;
265 if (wh >= MAX_WIN)
266 return -EINVAL;
267
268 req->Page = 0;
82f88e36 269 req->CardOffset = skt->win[wh].card_start;
d7b0364b
DB
270 return 0;
271} /* pcmcia_get_mem_page */
272
273
4aeba013
DB
274/** pccard_get_status
275 *
276 * Get the current socket state bits. We don't support the latched
277 * SocketState yet: I haven't seen any point for it.
278 */
279
280static int pccard_get_status(struct pcmcia_socket *s,
281 struct pcmcia_device *p_dev,
282 cs_status_t *status)
283{
284 config_t *c;
285 int val;
286
287 s->ops->get_status(s, &val);
288 status->CardState = status->SocketState = 0;
289 status->CardState |= (val & SS_DETECT) ? CS_EVENT_CARD_DETECT : 0;
290 status->CardState |= (val & SS_CARDBUS) ? CS_EVENT_CB_DETECT : 0;
291 status->CardState |= (val & SS_3VCARD) ? CS_EVENT_3VCARD : 0;
292 status->CardState |= (val & SS_XVCARD) ? CS_EVENT_XVCARD : 0;
293 if (s->state & SOCKET_SUSPEND)
294 status->CardState |= CS_EVENT_PM_SUSPEND;
295 if (!(s->state & SOCKET_PRESENT))
3939c1ef 296 return -ENODEV;
4aeba013
DB
297
298 c = (p_dev) ? p_dev->function_config : NULL;
299
300 if ((c != NULL) && (c->state & CONFIG_LOCKED) &&
301 (c->IntType & (INT_MEMORY_AND_IO | INT_ZOOMED_VIDEO))) {
302 u_char reg;
303 if (c->CardValues & PRESENT_PIN_REPLACE) {
059f667d 304 mutex_lock(&s->ops_mutex);
4aeba013 305 pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_PRR)>>1, 1, &reg);
059f667d 306 mutex_unlock(&s->ops_mutex);
4aeba013
DB
307 status->CardState |=
308 (reg & PRR_WP_STATUS) ? CS_EVENT_WRITE_PROTECT : 0;
309 status->CardState |=
310 (reg & PRR_READY_STATUS) ? CS_EVENT_READY_CHANGE : 0;
311 status->CardState |=
312 (reg & PRR_BVD2_STATUS) ? CS_EVENT_BATTERY_LOW : 0;
313 status->CardState |=
314 (reg & PRR_BVD1_STATUS) ? CS_EVENT_BATTERY_DEAD : 0;
315 } else {
316 /* No PRR? Then assume we're always ready */
317 status->CardState |= CS_EVENT_READY_CHANGE;
318 }
319 if (c->CardValues & PRESENT_EXT_STATUS) {
059f667d 320 mutex_lock(&s->ops_mutex);
4aeba013 321 pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_ESR)>>1, 1, &reg);
059f667d 322 mutex_unlock(&s->ops_mutex);
4aeba013
DB
323 status->CardState |=
324 (reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0;
325 }
4c89e88b 326 return 0;
4aeba013
DB
327 }
328 status->CardState |=
329 (val & SS_WRPROT) ? CS_EVENT_WRITE_PROTECT : 0;
330 status->CardState |=
331 (val & SS_BATDEAD) ? CS_EVENT_BATTERY_DEAD : 0;
332 status->CardState |=
333 (val & SS_BATWARN) ? CS_EVENT_BATTERY_LOW : 0;
334 status->CardState |=
335 (val & SS_READY) ? CS_EVENT_READY_CHANGE : 0;
4c89e88b 336 return 0;
4aeba013 337} /* pccard_get_status */
c5023801 338
a0779327 339static int pccard_get_configuration_info(struct pcmcia_socket *s,
64f34642
DB
340 struct pcmcia_device *p_dev,
341 config_info_t *config)
342{
343 config_t *c;
344
345 if (!(s->state & SOCKET_PRESENT))
3939c1ef 346 return -ENODEV;
64f34642
DB
347
348
349#ifdef CONFIG_CARDBUS
350 if (s->state & SOCKET_CARDBUS) {
351 memset(config, 0, sizeof(config_info_t));
352 config->Vcc = s->socket.Vcc;
353 config->Vpp1 = config->Vpp2 = s->socket.Vpp;
354 config->Option = s->cb_dev->subordinate->number;
355 if (s->state & SOCKET_CARDBUS_CONFIG) {
356 config->Attributes = CONF_VALID_CLIENT;
357 config->IntType = INT_CARDBUS;
6f840afb 358 config->AssignedIRQ = s->pcmcia_irq;
64f34642
DB
359 if (config->AssignedIRQ)
360 config->Attributes |= CONF_ENABLE_IRQ;
361 if (s->io[0].res) {
362 config->BasePort1 = s->io[0].res->start;
363 config->NumPorts1 = s->io[0].res->end -
364 config->BasePort1 + 1;
365 }
366 }
4c89e88b 367 return 0;
64f34642
DB
368 }
369#endif
370
371 if (p_dev) {
372 c = p_dev->function_config;
373 config->Function = p_dev->func;
374 } else {
375 c = NULL;
376 config->Function = 0;
377 }
378
379 if ((c == NULL) || !(c->state & CONFIG_LOCKED)) {
380 config->Attributes = 0;
381 config->Vcc = s->socket.Vcc;
382 config->Vpp1 = config->Vpp2 = s->socket.Vpp;
4c89e88b 383 return 0;
64f34642
DB
384 }
385
386 config->Attributes = c->Attributes | CONF_VALID_CLIENT;
387 config->Vcc = s->socket.Vcc;
388 config->Vpp1 = config->Vpp2 = s->socket.Vpp;
389 config->IntType = c->IntType;
390 config->ConfigBase = c->ConfigBase;
391 config->Status = c->Status;
392 config->Pin = c->Pin;
393 config->Copy = c->Copy;
394 config->Option = c->Option;
395 config->ExtStatus = c->ExtStatus;
396 config->Present = config->CardValues = c->CardValues;
397 config->IRQAttributes = c->irq.Attributes;
6f840afb 398 config->AssignedIRQ = s->pcmcia_irq;
64f34642
DB
399 config->BasePort1 = c->io.BasePort1;
400 config->NumPorts1 = c->io.NumPorts1;
401 config->Attributes1 = c->io.Attributes1;
402 config->BasePort2 = c->io.BasePort2;
403 config->NumPorts2 = c->io.NumPorts2;
404 config->Attributes2 = c->io.Attributes2;
405 config->IOAddrLines = c->io.IOAddrLines;
406
4c89e88b 407 return 0;
64f34642
DB
408} /* pccard_get_configuration_info */
409
410
e7a480d2
DB
411/*======================================================================
412
413 These manage a ring buffer of events pending for one user process
414
415======================================================================*/
416
417
418static int queue_empty(user_info_t *user)
419{
420 return (user->event_head == user->event_tail);
421}
422
423static event_t get_queued_event(user_info_t *user)
424{
425 user->event_tail = (user->event_tail+1) % MAX_EVENTS;
426 return user->event[user->event_tail];
427}
428
429static void queue_event(user_info_t *user, event_t event)
430{
431 user->event_head = (user->event_head+1) % MAX_EVENTS;
432 if (user->event_head == user->event_tail)
433 user->event_tail = (user->event_tail+1) % MAX_EVENTS;
434 user->event[user->event_head] = event;
435}
436
dc109497 437void handle_event(struct pcmcia_socket *s, event_t event)
e7a480d2
DB
438{
439 user_info_t *user;
440 for (user = s->user; user; user = user->next)
441 queue_event(user, event);
442 wake_up_interruptible(&s->queue);
443}
444
445
446/*======================================================================
447
448 bind_request() and bind_device() are merged by now. Register_client()
449 is called right at the end of bind_request(), during the driver's
450 ->attach() call. Individual descriptions:
451
452 bind_request() connects a socket to a particular client driver.
453 It looks up the specified device ID in the list of registered
454 drivers, binds it to the socket, and tries to create an instance
455 of the device. unbind_request() deletes a driver instance.
456
457 Bind_device() associates a device driver with a particular socket.
458 It is normally called by Driver Services after it has identified
459 a newly inserted card. An instance of that driver will then be
460 eligible to register as a client of this socket.
461
462 Register_client() uses the dev_info_t handle to match the
463 caller with a socket. The driver must have already been bound
464 to a socket with bind_device() -- in fact, bind_device()
465 allocates the client structure that will be used.
466
467======================================================================*/
468
dc109497 469static int bind_request(struct pcmcia_socket *s, bind_info_t *bind_info)
e7a480d2
DB
470{
471 struct pcmcia_driver *p_drv;
472 struct pcmcia_device *p_dev;
473 int ret = 0;
e7a480d2 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
00ce99ff 493 mutex_lock(&s->ops_mutex);
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". */
00ce99ff 502 mutex_unlock(&s->ops_mutex);
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. */
00ce99ff 510 mutex_unlock(&s->ops_mutex);
e7a480d2
DB
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! */
00ce99ff 519 mutex_unlock(&s->ops_mutex);
e7a480d2
DB
520 goto rescan;
521 }
522 }
523 }
00ce99ff 524 mutex_unlock(&s->ops_mutex);
e7a480d2
DB
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 577{
e7a480d2 578 struct pcmcia_device *p_dev;
e2d40963 579 struct pcmcia_driver *p_drv;
e7a480d2
DB
580 int ret = 0;
581
582#ifdef CONFIG_CARDBUS
583 /*
584 * Some unbelievably ugly code to associate the PCI cardbus
585 * device and its driver with the PCMCIA "bind" information.
586 */
587 {
588 struct pci_bus *bus;
589
dc109497 590 bus = pcmcia_lookup_bus(s);
e7a480d2
DB
591 if (bus) {
592 struct list_head *list;
593 struct pci_dev *dev = NULL;
594
595 list = bus->devices.next;
596 while (list != &bus->devices) {
597 struct pci_dev *pdev = pci_dev_b(list);
598 list = list->next;
599
600 if (first) {
601 dev = pdev;
602 break;
603 }
604
605 /* Try to handle "next" here some way? */
606 }
607 if (dev && dev->driver) {
608 strlcpy(bind_info->name, dev->driver->name, DEV_NAME_LEN);
609 bind_info->major = 0;
610 bind_info->minor = 0;
611 bind_info->next = NULL;
612 return 0;
613 }
614 }
615 }
616#endif
617
00ce99ff 618 mutex_lock(&s->ops_mutex);
e7a480d2
DB
619 list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
620 if (p_dev->func == bind_info->function) {
621 p_dev = pcmcia_get_dev(p_dev);
622 if (!p_dev)
623 continue;
624 goto found;
625 }
626 }
00ce99ff 627 mutex_unlock(&s->ops_mutex);
e7a480d2
DB
628 return -ENODEV;
629
630 found:
00ce99ff 631 mutex_unlock(&s->ops_mutex);
e7a480d2 632
e2d40963
DB
633 p_drv = to_pcmcia_drv(p_dev->dev.driver);
634 if (p_drv && !p_dev->_locked) {
e7a480d2
DB
635 ret = -EAGAIN;
636 goto err_put;
637 }
638
b9300aa7 639 if (!first) {
e7a480d2
DB
640 ret = -ENODEV;
641 goto err_put;
642 }
643
b9300aa7
DB
644 strlcpy(bind_info->name, dev_name(&p_dev->dev), DEV_NAME_LEN);
645 bind_info->next = NULL;
e7a480d2
DB
646
647 err_put:
648 pcmcia_put_dev(p_dev);
9fea84f4 649 return ret;
e7a480d2
DB
650} /* get_device_info */
651
652
653static int ds_open(struct inode *inode, struct file *file)
654{
655 socket_t i = iminor(inode);
dc109497 656 struct pcmcia_socket *s;
e7a480d2 657 user_info_t *user;
9fea84f4 658 static int warning_printed;
0bec0bba 659 int ret = 0;
e7a480d2 660
d50dbec3 661 pr_debug("ds_open(socket %d)\n", i);
e7a480d2 662
0bec0bba 663 lock_kernel();
dc109497 664 s = pcmcia_get_socket_by_nr(i);
0bec0bba
JC
665 if (!s) {
666 ret = -ENODEV;
667 goto out;
668 }
dc109497 669 s = pcmcia_get_socket(s);
0bec0bba
JC
670 if (!s) {
671 ret = -ENODEV;
672 goto out;
673 }
e7a480d2
DB
674
675 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
b5e43913 676 if (s->pcmcia_state.busy) {
dc109497 677 pcmcia_put_socket(s);
0bec0bba
JC
678 ret = -EBUSY;
679 goto out;
e7a480d2
DB
680 }
681 else
b5e43913 682 s->pcmcia_state.busy = 1;
e7a480d2
DB
683 }
684
685 user = kmalloc(sizeof(user_info_t), GFP_KERNEL);
686 if (!user) {
dc109497 687 pcmcia_put_socket(s);
0bec0bba
JC
688 ret = -ENOMEM;
689 goto out;
e7a480d2
DB
690 }
691 user->event_tail = user->event_head = 0;
692 user->next = s->user;
693 user->user_magic = USER_MAGIC;
694 user->socket = s;
695 s->user = user;
696 file->private_data = user;
697
c352ec8a
DB
698 if (!warning_printed) {
699 printk(KERN_INFO "pcmcia: Detected deprecated PCMCIA ioctl "
73d58588 700 "usage from process: %s.\n", current->comm);
c352ec8a
DB
701 printk(KERN_INFO "pcmcia: This interface will soon be removed from "
702 "the kernel; please expect breakage unless you upgrade "
703 "to new tools.\n");
704 printk(KERN_INFO "pcmcia: see http://www.kernel.org/pub/linux/"
705 "utils/kernel/pcmcia/pcmcia.html for details.\n");
706 warning_printed = 1;
707 }
708
15d0a873 709 if (atomic_read(&s->present))
e7a480d2 710 queue_event(user, CS_EVENT_CARD_INSERTION);
0bec0bba
JC
711out:
712 unlock_kernel();
713 return ret;
e7a480d2
DB
714} /* ds_open */
715
716/*====================================================================*/
717
718static int ds_release(struct inode *inode, struct file *file)
719{
dc109497 720 struct pcmcia_socket *s;
e7a480d2
DB
721 user_info_t *user, **link;
722
d50dbec3 723 pr_debug("ds_release(socket %d)\n", iminor(inode));
e7a480d2
DB
724
725 user = file->private_data;
726 if (CHECK_USER(user))
727 goto out;
728
729 s = user->socket;
730
731 /* Unlink user data structure */
9fea84f4 732 if ((file->f_flags & O_ACCMODE) != O_RDONLY)
b5e43913 733 s->pcmcia_state.busy = 0;
9fea84f4 734
e7a480d2
DB
735 file->private_data = NULL;
736 for (link = &s->user; *link; link = &(*link)->next)
9fea84f4
DB
737 if (*link == user)
738 break;
e7a480d2
DB
739 if (link == NULL)
740 goto out;
741 *link = user->next;
742 user->user_magic = 0;
743 kfree(user);
dc109497 744 pcmcia_put_socket(s);
e7a480d2
DB
745out:
746 return 0;
747} /* ds_release */
748
749/*====================================================================*/
750
751static ssize_t ds_read(struct file *file, char __user *buf,
752 size_t count, loff_t *ppos)
753{
dc109497 754 struct pcmcia_socket *s;
e7a480d2
DB
755 user_info_t *user;
756 int ret;
757
d50dbec3 758 pr_debug("ds_read(socket %d)\n", iminor(file->f_path.dentry->d_inode));
e7a480d2
DB
759
760 if (count < 4)
761 return -EINVAL;
762
763 user = file->private_data;
764 if (CHECK_USER(user))
765 return -EIO;
766
767 s = user->socket;
e7a480d2
DB
768 ret = wait_event_interruptible(s->queue, !queue_empty(user));
769 if (ret == 0)
770 ret = put_user(get_queued_event(user), (int __user *)buf) ? -EFAULT : 4;
771
772 return ret;
773} /* ds_read */
774
775/*====================================================================*/
776
777static ssize_t ds_write(struct file *file, const char __user *buf,
778 size_t count, loff_t *ppos)
779{
d50dbec3 780 pr_debug("ds_write(socket %d)\n", iminor(file->f_path.dentry->d_inode));
e7a480d2
DB
781
782 if (count != 4)
783 return -EINVAL;
784 if ((file->f_flags & O_ACCMODE) == O_RDONLY)
785 return -EBADF;
786
787 return -EIO;
788} /* ds_write */
789
790/*====================================================================*/
791
792/* No kernel lock - fine */
793static u_int ds_poll(struct file *file, poll_table *wait)
794{
dc109497 795 struct pcmcia_socket *s;
e7a480d2
DB
796 user_info_t *user;
797
d50dbec3 798 pr_debug("ds_poll(socket %d)\n", iminor(file->f_path.dentry->d_inode));
e7a480d2
DB
799
800 user = file->private_data;
801 if (CHECK_USER(user))
802 return POLLERR;
803 s = user->socket;
804 /*
805 * We don't check for a dead socket here since that
806 * will send cardmgr into an endless spin.
807 */
808 poll_wait(file, &s->queue, wait);
809 if (!queue_empty(user))
810 return POLLIN | POLLRDNORM;
811 return 0;
812} /* ds_poll */
813
814/*====================================================================*/
815
55929332 816static int ds_ioctl(struct file *file, u_int cmd, u_long arg)
e7a480d2 817{
dc109497 818 struct pcmcia_socket *s;
e7a480d2
DB
819 void __user *uarg = (char __user *)arg;
820 u_int size;
821 int ret, err;
822 ds_ioctl_arg_t *buf;
823 user_info_t *user;
824
d50dbec3 825 pr_debug("ds_ioctl(socket %d, %#x, %#lx)\n", iminor(inode), cmd, arg);
e7a480d2
DB
826
827 user = file->private_data;
828 if (CHECK_USER(user))
829 return -EIO;
830
831 s = user->socket;
e7a480d2
DB
832
833 size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
9fea84f4
DB
834 if (size > sizeof(ds_ioctl_arg_t))
835 return -EINVAL;
e7a480d2
DB
836
837 /* Permission check */
838 if (!(cmd & IOC_OUT) && !capable(CAP_SYS_ADMIN))
839 return -EPERM;
840
841 if (cmd & IOC_IN) {
842 if (!access_ok(VERIFY_READ, uarg, size)) {
d50dbec3 843 pr_debug("ds_ioctl(): verify_read = %d\n", -EFAULT);
e7a480d2
DB
844 return -EFAULT;
845 }
846 }
847 if (cmd & IOC_OUT) {
848 if (!access_ok(VERIFY_WRITE, uarg, size)) {
d50dbec3 849 pr_debug("ds_ioctl(): verify_write = %d\n", -EFAULT);
e7a480d2
DB
850 return -EFAULT;
851 }
852 }
853 buf = kmalloc(sizeof(ds_ioctl_arg_t), GFP_KERNEL);
854 if (!buf)
855 return -ENOMEM;
856
857 err = ret = 0;
858
9374074f
DB
859 if (cmd & IOC_IN) {
860 if (__copy_from_user((char *)buf, uarg, size)) {
861 err = -EFAULT;
862 goto free_out;
863 }
864 }
e7a480d2
DB
865
866 switch (cmd) {
867 case DS_ADJUST_RESOURCE_INFO:
868 ret = pcmcia_adjust_resource_info(&buf->adjust);
869 break;
e7a480d2
DB
870 case DS_GET_CONFIGURATION_INFO:
871 if (buf->config.Function &&
dc109497 872 (buf->config.Function >= s->functions))
926c5402 873 ret = -EINVAL;
855cdf13
DB
874 else {
875 struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->config.Function);
f47ad214
DR
876 ret = pccard_get_configuration_info(s, p_dev, &buf->config);
877 pcmcia_put_dev(p_dev);
855cdf13 878 }
e7a480d2
DB
879 break;
880 case DS_GET_FIRST_TUPLE:
7fe908dd 881 mutex_lock(&s->skt_mutex);
dc109497 882 pcmcia_validate_mem(s);
7fe908dd 883 mutex_unlock(&s->skt_mutex);
dc109497 884 ret = pccard_get_first_tuple(s, BIND_FN_ALL, &buf->tuple);
e7a480d2
DB
885 break;
886 case DS_GET_NEXT_TUPLE:
dc109497 887 ret = pccard_get_next_tuple(s, BIND_FN_ALL, &buf->tuple);
e7a480d2
DB
888 break;
889 case DS_GET_TUPLE_DATA:
890 buf->tuple.TupleData = buf->tuple_parse.data;
891 buf->tuple.TupleDataMax = sizeof(buf->tuple_parse.data);
dc109497 892 ret = pccard_get_tuple_data(s, &buf->tuple);
e7a480d2
DB
893 break;
894 case DS_PARSE_TUPLE:
895 buf->tuple.TupleData = buf->tuple_parse.data;
2f3061eb 896 ret = pcmcia_parse_tuple(&buf->tuple, &buf->tuple_parse.parse);
e7a480d2
DB
897 break;
898 case DS_RESET_CARD:
994917f8 899 ret = pcmcia_reset_card(s);
e7a480d2
DB
900 break;
901 case DS_GET_STATUS:
855cdf13
DB
902 if (buf->status.Function &&
903 (buf->status.Function >= s->functions))
926c5402 904 ret = -EINVAL;
855cdf13
DB
905 else {
906 struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->status.Function);
f47ad214
DR
907 ret = pccard_get_status(s, p_dev, &buf->status);
908 pcmcia_put_dev(p_dev);
855cdf13
DB
909 }
910 break;
e7a480d2 911 case DS_VALIDATE_CIS:
7fe908dd 912 mutex_lock(&s->skt_mutex);
dc109497 913 pcmcia_validate_mem(s);
7fe908dd 914 mutex_unlock(&s->skt_mutex);
84897fc0 915 ret = pccard_validate_cis(s, &buf->cisinfo.Chains);
e7a480d2
DB
916 break;
917 case DS_SUSPEND_CARD:
f971dbd5 918 pcmcia_parse_uevents(s, PCMCIA_UEVENT_SUSPEND);
e7a480d2
DB
919 break;
920 case DS_RESUME_CARD:
f971dbd5 921 pcmcia_parse_uevents(s, PCMCIA_UEVENT_RESUME);
e7a480d2
DB
922 break;
923 case DS_EJECT_CARD:
f971dbd5 924 pcmcia_parse_uevents(s, PCMCIA_UEVENT_EJECT);
e7a480d2
DB
925 break;
926 case DS_INSERT_CARD:
f971dbd5 927 pcmcia_parse_uevents(s, PCMCIA_UEVENT_INSERT);
e7a480d2
DB
928 break;
929 case DS_ACCESS_CONFIGURATION_REGISTER:
930 if ((buf->conf_reg.Action == CS_WRITE) && !capable(CAP_SYS_ADMIN)) {
931 err = -EPERM;
932 goto free_out;
933 }
855cdf13 934
926c5402 935 ret = -EINVAL;
855cdf13
DB
936
937 if (!(buf->conf_reg.Function &&
938 (buf->conf_reg.Function >= s->functions))) {
939 struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->conf_reg.Function);
73d58588 940 if (p_dev) {
855cdf13 941 ret = pcmcia_access_configuration_register(p_dev, &buf->conf_reg);
73d58588
BH
942 pcmcia_put_dev(p_dev);
943 }
855cdf13 944 }
e7a480d2
DB
945 break;
946 case DS_GET_FIRST_REGION:
947 case DS_GET_NEXT_REGION:
948 case DS_BIND_MTD:
949 if (!capable(CAP_SYS_ADMIN)) {
950 err = -EPERM;
951 goto free_out;
952 } else {
a9c56953
MK
953 printk_once(KERN_WARNING
954 "2.6. kernels use pcmciamtd instead of memory_cs.c and do not require special\n");
955 printk_once(KERN_WARNING "MTD handling any more.\n");
e7a480d2
DB
956 }
957 err = -EINVAL;
958 goto free_out;
959 break;
960 case DS_GET_FIRST_WINDOW:
0bdf9b3d 961 ret = pcmcia_get_window(s, &buf->win_info.handle, 1,
e7a480d2
DB
962 &buf->win_info.window);
963 break;
964 case DS_GET_NEXT_WINDOW:
dc109497 965 ret = pcmcia_get_window(s, &buf->win_info.handle,
0bdf9b3d 966 buf->win_info.handle + 1, &buf->win_info.window);
e7a480d2
DB
967 break;
968 case DS_GET_MEM_PAGE:
16456eba 969 ret = pcmcia_get_mem_page(s, buf->win_info.handle,
e7a480d2
DB
970 &buf->win_info.map);
971 break;
972 case DS_REPLACE_CIS:
53efec95 973 ret = pcmcia_replace_cis(s, buf->cisdump.Data, buf->cisdump.Length);
e7a480d2
DB
974 break;
975 case DS_BIND_REQUEST:
976 if (!capable(CAP_SYS_ADMIN)) {
977 err = -EPERM;
978 goto free_out;
979 }
980 err = bind_request(s, &buf->bind_info);
981 break;
982 case DS_GET_DEVICE_INFO:
983 err = get_device_info(s, &buf->bind_info, 1);
984 break;
985 case DS_GET_NEXT_DEVICE:
986 err = get_device_info(s, &buf->bind_info, 0);
987 break;
988 case DS_UNBIND_REQUEST:
989 err = 0;
990 break;
991 default:
992 err = -EINVAL;
993 }
994
4c89e88b 995 if ((err == 0) && (ret != 0)) {
d50dbec3 996 pr_debug("ds_ioctl: ret = %d\n", ret);
e7a480d2 997 switch (ret) {
610e2374
DB
998 case -ENODEV:
999 case -EINVAL:
1000 case -EBUSY:
1001 case -ENOSYS:
1002 err = ret;
1003 break;
610e2374 1004 case -ENOMEM:
e7a480d2 1005 err = -ENOSPC; break;
635d19be 1006 case -ENOSPC:
e7a480d2 1007 err = -ENODATA; break;
e7a480d2
DB
1008 default:
1009 err = -EIO; break;
1010 }
1011 }
1012
1013 if (cmd & IOC_OUT) {
9fea84f4
DB
1014 if (__copy_to_user(uarg, (char *)buf, size))
1015 err = -EFAULT;
e7a480d2
DB
1016 }
1017
1018free_out:
1019 kfree(buf);
1020 return err;
1021} /* ds_ioctl */
1022
55929332
AB
1023static long ds_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1024{
1025 int ret;
1026
1027 lock_kernel();
1028 ret = ds_ioctl(file, cmd, arg);
1029 unlock_kernel();
1030
1031 return ret;
1032}
1033
1034
e7a480d2
DB
1035/*====================================================================*/
1036
d54b1fdb 1037static const struct file_operations ds_fops = {
e7a480d2
DB
1038 .owner = THIS_MODULE,
1039 .open = ds_open,
1040 .release = ds_release,
55929332 1041 .unlocked_ioctl = ds_unlocked_ioctl,
e7a480d2
DB
1042 .read = ds_read,
1043 .write = ds_write,
1044 .poll = ds_poll,
1045};
1046
9fea84f4
DB
1047void __init pcmcia_setup_ioctl(void)
1048{
e7a480d2
DB
1049 int i;
1050
1051 /* Set up character device for user mode clients */
1052 i = register_chrdev(0, "pcmcia", &ds_fops);
1a8ceafc 1053 if (i < 0)
e7a480d2 1054 printk(KERN_NOTICE "unable to find a free device # for "
1a8ceafc 1055 "Driver Services (error=%d)\n", i);
e7a480d2
DB
1056 else
1057 major_dev = i;
1058
1059#ifdef CONFIG_PROC_FS
97094dcf 1060 proc_pccard = proc_mkdir("bus/pccard", NULL);
e7a480d2 1061 if (proc_pccard)
e6be4a8c 1062 proc_create("drivers", 0, proc_pccard, &pccard_drivers_proc_fops);
e7a480d2
DB
1063#endif
1064}
1065
1066
9fea84f4
DB
1067void __exit pcmcia_cleanup_ioctl(void)
1068{
e7a480d2
DB
1069#ifdef CONFIG_PROC_FS
1070 if (proc_pccard) {
1071 remove_proc_entry("drivers", proc_pccard);
97094dcf 1072 remove_proc_entry("bus/pccard", NULL);
e7a480d2
DB
1073 }
1074#endif
1075 if (major_dev != -1)
1076 unregister_chrdev(major_dev, "pcmcia");
1077}