linux/drivers/staging/meilhaus/me1000_device.c
<<
>>
Prefs
   1/**
   2 * @file me1000_device.c
   3 *
   4 * @brief ME-1000 device class implementation.
   5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
   6 * @author Guenter Gebhardt
   7 * @author Krzysztof Gantzke    (k.gantzke@meilhaus.de)
   8 */
   9
  10/*
  11 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
  12 *
  13 * This file is free software; you can redistribute it and/or modify
  14 * it under the terms of the GNU General Public License as published by
  15 * the Free Software Foundation; either version 2 of the License, or
  16 * (at your option) any later version.
  17 *
  18 * This program is distributed in the hope that it will be useful,
  19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21 * GNU General Public License for more details.
  22 *
  23 * You should have received a copy of the GNU General Public License
  24 * along with this program; if not, write to the Free Software
  25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  26 */
  27
  28#ifndef __KERNEL__
  29#  define __KERNEL__
  30#endif
  31
  32#ifndef MODULE
  33#  define MODULE
  34#endif
  35
  36#include <linux/module.h>
  37
  38#include <linux/pci.h>
  39#include <linux/slab.h>
  40
  41#include "meids.h"
  42#include "meerror.h"
  43#include "mecommon.h"
  44#include "meinternal.h"
  45
  46#include "medebug.h"
  47#include "medevice.h"
  48#include "me1000_device.h"
  49#include "mesubdevice.h"
  50#include "me1000_dio.h"
  51
  52static int me1000_config_load(me_device_t * me_device, struct file *filep,
  53                              me_cfg_device_entry_t * config)
  54{
  55        me1000_device_t *me1000_device;
  56        me1000_dio_subdevice_t *dio;
  57
  58        PDEBUG("executed.\n");
  59
  60        me1000_device = (me1000_device_t *) me_device;
  61
  62        if (config->count == 2) {
  63                if (me_slist_get_number_subdevices(&me1000_device->base.slist)
  64                    == 2) {
  65                        // Nothing to do.
  66                } else {
  67                        // Remove 2 extra subdevices
  68                        dio =
  69                            (me1000_dio_subdevice_t *)
  70                            me_slist_del_subdevice_tail(&me1000_device->base.
  71                                                        slist);
  72                        if (dio)
  73                                dio->base.
  74                                    me_subdevice_destructor((me_subdevice_t *)
  75                                                            dio);
  76
  77                        dio =
  78                            (me1000_dio_subdevice_t *)
  79                            me_slist_del_subdevice_tail(&me1000_device->base.
  80                                                        slist);
  81                        if (dio)
  82                                dio->base.
  83                                    me_subdevice_destructor((me_subdevice_t *)
  84                                                            dio);
  85                }
  86        } else if (config->count == 4) {
  87                //Add 2 subdevices
  88                if (me_slist_get_number_subdevices(&me1000_device->base.slist)
  89                    == 2) {
  90                        dio =
  91                            me1000_dio_constructor(me1000_device->base.info.pci.
  92                                                   reg_bases[2], 2,
  93                                                   &me1000_device->ctrl_lock);
  94                        if (!dio) {
  95                                PERROR("Cannot create dio subdevice.\n");
  96                                return ME_ERRNO_INTERNAL;
  97                        }
  98                        me_slist_add_subdevice_tail(&me1000_device->base.slist,
  99                                                    (me_subdevice_t *) dio);
 100
 101                        dio =
 102                            me1000_dio_constructor(me1000_device->base.info.pci.
 103                                                   reg_bases[2], 3,
 104                                                   &me1000_device->ctrl_lock);
 105                        if (!dio) {
 106                                dio =
 107                                    (me1000_dio_subdevice_t *)
 108                                    me_slist_del_subdevice_tail(&me1000_device->
 109                                                                base.slist);
 110                                if (dio)
 111                                        dio->base.
 112                                            me_subdevice_destructor((me_subdevice_t *) dio);
 113
 114                                PERROR("Cannot create dio subdevice.\n");
 115                                return ME_ERRNO_INTERNAL;
 116                        }
 117                        me_slist_add_subdevice_tail(&me1000_device->base.slist,
 118                                                    (me_subdevice_t *) dio);
 119                } else {
 120                        // Nothing to do.
 121                }
 122        } else {
 123                PERROR("Invalid configuration.\n");
 124                return ME_ERRNO_INTERNAL;
 125        }
 126
 127        return ME_ERRNO_SUCCESS;
 128}
 129
 130me_device_t *me1000_pci_constructor(struct pci_dev * pci_device)
 131{
 132        me1000_device_t *me1000_device;
 133        me_subdevice_t *subdevice;
 134        int err;
 135        int i;
 136
 137        PDEBUG("executed.\n");
 138
 139        // Allocate structure for device instance.
 140        me1000_device = kmalloc(sizeof(me1000_device_t), GFP_KERNEL);
 141
 142        if (!me1000_device) {
 143                PERROR("Cannot get memory for ME-1000 device instance.\n");
 144                return NULL;
 145        }
 146
 147        memset(me1000_device, 0, sizeof(me1000_device_t));
 148
 149        // Initialize base class structure.
 150        err = me_device_pci_init((me_device_t *) me1000_device, pci_device);
 151
 152        if (err) {
 153                kfree(me1000_device);
 154                PERROR("Cannot initialize device base class.\n");
 155                return NULL;
 156        }
 157        // Initialize spin lock .
 158        spin_lock_init(&me1000_device->ctrl_lock);
 159
 160        for (i = 0; i < 4; i++) {
 161                subdevice =
 162                    (me_subdevice_t *) me1000_dio_constructor(me1000_device->
 163                                                              base.info.pci.
 164                                                              reg_bases[2], i,
 165                                                              &me1000_device->
 166                                                              ctrl_lock);
 167
 168                if (!subdevice) {
 169                        me_device_deinit((me_device_t *) me1000_device);
 170                        kfree(me1000_device);
 171                        PERROR("Cannot get memory for subdevice.\n");
 172                        return NULL;
 173                }
 174
 175                me_slist_add_subdevice_tail(&me1000_device->base.slist,
 176                                            subdevice);
 177        }
 178
 179        // Overwrite base class methods.
 180        me1000_device->base.me_device_config_load = me1000_config_load;
 181
 182        return (me_device_t *) me1000_device;
 183}
 184
 185// Init and exit of module.
 186static int __init me1000_init(void)
 187{
 188        PDEBUG("executed.\n");
 189        return 0;
 190}
 191
 192static void __exit me1000_exit(void)
 193{
 194        PDEBUG("executed.\n");
 195}
 196
 197module_init(me1000_init);
 198module_exit(me1000_exit);
 199
 200// Administrative stuff for modinfo.
 201MODULE_AUTHOR
 202    ("Guenter Gebhardt <g.gebhardt@meilhaus.de> & Krzysztof Gantzke <k.gantzke@meilhaus.de>");
 203MODULE_DESCRIPTION("Device Driver Module for Meilhaus ME-1000 Devices");
 204MODULE_SUPPORTED_DEVICE("Meilhaus ME-1000 Digital I/O Devices");
 205MODULE_LICENSE("GPL");
 206
 207// Export the constructor.
 208EXPORT_SYMBOL(me1000_pci_constructor);
 209
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.