linux/drivers/staging/meilhaus/me0600_device.c
<<
>>
Prefs
   1/**
   2 * @file me0600_device.c
   3 *
   4 * @brief ME-630 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 "me0600_device.h"
  49#include "mesubdevice.h"
  50#include "me0600_relay.h"
  51#include "me0600_ttli.h"
  52#include "me0600_optoi.h"
  53#include "me0600_dio.h"
  54#include "me0600_ext_irq.h"
  55
  56me_device_t *me0600_pci_constructor(struct pci_dev *pci_device)
  57{
  58        me0600_device_t *me0600_device;
  59        me_subdevice_t *subdevice;
  60        unsigned int version_idx;
  61        int err;
  62        int i;
  63
  64        PDEBUG("executed.\n");
  65
  66        // Allocate structure for device instance.
  67        me0600_device = kmalloc(sizeof(me0600_device_t), GFP_KERNEL);
  68
  69        if (!me0600_device) {
  70                PERROR("Cannot get memory for device instance.\n");
  71                return NULL;
  72        }
  73
  74        memset(me0600_device, 0, sizeof(me0600_device_t));
  75
  76        // Initialize base class structure.
  77        err = me_device_pci_init((me_device_t *) me0600_device, pci_device);
  78
  79        if (err) {
  80                kfree(me0600_device);
  81                PERROR("Cannot initialize device base class.\n");
  82                return NULL;
  83        }
  84
  85        /* Get the index in the device version information table. */
  86        version_idx =
  87            me0600_versions_get_device_index(me0600_device->base.info.pci.
  88                                             device_id);
  89
  90        // Initialize spin lock .
  91        spin_lock_init(&me0600_device->dio_ctrl_reg_lock);
  92        spin_lock_init(&me0600_device->intcsr_lock);
  93
  94        // Create subdevice instances.
  95
  96        for (i = 0; i < me0600_versions[version_idx].optoi_subdevices; i++) {
  97                subdevice =
  98                    (me_subdevice_t *) me0600_optoi_constructor(me0600_device->
  99                                                                base.info.pci.
 100                                                                reg_bases[2]);
 101
 102                if (!subdevice) {
 103                        me_device_deinit((me_device_t *) me0600_device);
 104                        kfree(me0600_device);
 105                        PERROR("Cannot get memory for subdevice.\n");
 106                        return NULL;
 107                }
 108
 109                me_slist_add_subdevice_tail(&me0600_device->base.slist,
 110                                            subdevice);
 111        }
 112
 113        for (i = 0; i < me0600_versions[version_idx].relay_subdevices; i++) {
 114                subdevice =
 115                    (me_subdevice_t *) me0600_relay_constructor(me0600_device->
 116                                                                base.info.pci.
 117                                                                reg_bases[2]);
 118
 119                if (!subdevice) {
 120                        me_device_deinit((me_device_t *) me0600_device);
 121                        kfree(me0600_device);
 122                        PERROR("Cannot get memory for subdevice.\n");
 123                        return NULL;
 124                }
 125
 126                me_slist_add_subdevice_tail(&me0600_device->base.slist,
 127                                            subdevice);
 128        }
 129
 130        for (i = 0; i < me0600_versions[version_idx].ttli_subdevices; i++) {
 131                subdevice =
 132                    (me_subdevice_t *) me0600_ttli_constructor(me0600_device->
 133                                                               base.info.pci.
 134                                                               reg_bases[2]);
 135
 136                if (!subdevice) {
 137                        me_device_deinit((me_device_t *) me0600_device);
 138                        kfree(me0600_device);
 139                        PERROR("Cannot get memory for subdevice.\n");
 140                        return NULL;
 141                }
 142
 143                me_slist_add_subdevice_tail(&me0600_device->base.slist,
 144                                            subdevice);
 145        }
 146
 147        for (i = 0; i < me0600_versions[version_idx].dio_subdevices; i++) {
 148                subdevice =
 149                    (me_subdevice_t *) me0600_dio_constructor(me0600_device->
 150                                                              base.info.pci.
 151                                                              reg_bases[2], i,
 152                                                              &me0600_device->
 153                                                              dio_ctrl_reg_lock);
 154
 155                if (!subdevice) {
 156                        me_device_deinit((me_device_t *) me0600_device);
 157                        kfree(me0600_device);
 158                        PERROR("Cannot get memory for subdevice.\n");
 159                        return NULL;
 160                }
 161
 162                me_slist_add_subdevice_tail(&me0600_device->base.slist,
 163                                            subdevice);
 164        }
 165
 166        for (i = 0; i < me0600_versions[version_idx].ext_irq_subdevices; i++) {
 167                subdevice =
 168                    (me_subdevice_t *)
 169                    me0600_ext_irq_constructor(me0600_device->base.info.pci.
 170                                               reg_bases[1],
 171                                               me0600_device->base.info.pci.
 172                                               reg_bases[2],
 173                                               &me0600_device->intcsr_lock, i,
 174                                               me0600_device->base.irq);
 175
 176                if (!subdevice) {
 177                        me_device_deinit((me_device_t *) me0600_device);
 178                        kfree(me0600_device);
 179                        PERROR("Cannot get memory for subdevice.\n");
 180                        return NULL;
 181                }
 182
 183                me_slist_add_subdevice_tail(&me0600_device->base.slist,
 184                                            subdevice);
 185        }
 186
 187        return (me_device_t *) me0600_device;
 188}
 189
 190// Init and exit of module.
 191
 192static int __init me0600_init(void)
 193{
 194        PDEBUG("executed.\n");
 195        return 0;
 196}
 197
 198static void __exit me0600_exit(void)
 199{
 200        PDEBUG("executed.\n");
 201}
 202
 203module_init(me0600_init);
 204
 205module_exit(me0600_exit);
 206
 207// Administrative stuff for modinfo.
 208MODULE_AUTHOR
 209    ("Guenter Gebhardt <g.gebhardt@meilhaus.de> & Krzysztof Gantzke <k.gantzke@meilhaus.de>");
 210MODULE_DESCRIPTION("Device Driver Module for ME-6xx Device");
 211MODULE_SUPPORTED_DEVICE("Meilhaus ME-6xx Devices");
 212MODULE_LICENSE("GPL");
 213
 214// Export the constructor.
 215EXPORT_SYMBOL(me0600_pci_constructor);
 216
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.