Root/drivers/pcmcia/pcmcia_ioctl.c

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

Archive Download this file



interactive