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