linux/drivers/staging/meilhaus/me8200_device.c
<<
>>
Prefs
   1/**
   2 * @file me8200_device.c
   3 *
   4 * @brief ME-8200 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 "meplx_reg.h"
  48#include "medevice.h"
  49#include "me8200_device.h"
  50#include "mesubdevice.h"
  51#include "me8200_di.h"
  52#include "me8200_do.h"
  53#include "me8200_dio.h"
  54
  55me_device_t *me8200_pci_constructor(struct pci_dev *pci_device)
  56{
  57        me8200_device_t *me8200_device;
  58        me_subdevice_t *subdevice;
  59        unsigned int version_idx;
  60        int err;
  61        int i;
  62
  63        PDEBUG("executed.\n");
  64
  65        // Allocate structure for device instance.
  66        me8200_device = kmalloc(sizeof(me8200_device_t), GFP_KERNEL);
  67
  68        if (!me8200_device) {
  69                PERROR("Cannot get memory for device instance.\n");
  70                return NULL;
  71        }
  72
  73        memset(me8200_device, 0, sizeof(me8200_device_t));
  74
  75        // Initialize base class structure.
  76        err = me_device_pci_init((me_device_t *) me8200_device, pci_device);
  77
  78        if (err) {
  79                kfree(me8200_device);
  80                PERROR("Cannot initialize device base class.\n");
  81                return NULL;
  82        }
  83
  84        /* Get the index in the device version information table. */
  85        version_idx =
  86            me8200_versions_get_device_index(me8200_device->base.info.pci.
  87                                             device_id);
  88
  89        // Initialize spin lock .
  90        spin_lock_init(&me8200_device->irq_ctrl_lock);
  91        spin_lock_init(&me8200_device->irq_mode_lock);
  92        spin_lock_init(&me8200_device->dio_ctrl_lock);
  93
  94        /* Setup the PLX interrupt configuration */
  95        outl(PLX_INTCSR_LOCAL_INT1_EN |
  96             PLX_INTCSR_LOCAL_INT1_POL |
  97             PLX_INTCSR_LOCAL_INT2_EN |
  98             PLX_INTCSR_LOCAL_INT2_POL |
  99             PLX_INTCSR_PCI_INT_EN,
 100             me8200_device->base.info.pci.reg_bases[1] + PLX_INTCSR);
 101
 102        // Create subdevice instances.
 103
 104        for (i = 0; i < me8200_versions[version_idx].di_subdevices; i++) {
 105                subdevice =
 106                    (me_subdevice_t *) me8200_di_constructor(me8200_device->
 107                                                             base.info.pci.
 108                                                             reg_bases[2], i,
 109                                                             me8200_device->
 110                                                             base.irq,
 111                                                             &me8200_device->
 112                                                             irq_ctrl_lock,
 113                                                             &me8200_device->
 114                                                             irq_mode_lock);
 115
 116                if (!subdevice) {
 117                        me_device_deinit((me_device_t *) me8200_device);
 118                        kfree(me8200_device);
 119                        PERROR("Cannot get memory for subdevice.\n");
 120                        return NULL;
 121                }
 122
 123                me_slist_add_subdevice_tail(&me8200_device->base.slist,
 124                                            subdevice);
 125        }
 126
 127        for (i = 0; i < me8200_versions[version_idx].do_subdevices; i++) {
 128                subdevice =
 129                    (me_subdevice_t *) me8200_do_constructor(me8200_device->
 130                                                             base.info.pci.
 131                                                             reg_bases[2], i,
 132                                                             me8200_device->
 133                                                             base.irq,
 134                                                             &me8200_device->
 135                                                             irq_mode_lock);
 136
 137                if (!subdevice) {
 138                        me_device_deinit((me_device_t *) me8200_device);
 139                        kfree(me8200_device);
 140                        PERROR("Cannot get memory for subdevice.\n");
 141                        return NULL;
 142                }
 143
 144                me_slist_add_subdevice_tail(&me8200_device->base.slist,
 145                                            subdevice);
 146        }
 147
 148        for (i = 0; i < me8200_versions[version_idx].dio_subdevices; i++) {
 149                subdevice =
 150                    (me_subdevice_t *) me8200_dio_constructor(me8200_device->
 151                                                              base.info.pci.
 152                                                              reg_bases[2], i,
 153                                                              &me8200_device->
 154                                                              dio_ctrl_lock);
 155
 156                if (!subdevice) {
 157                        me_device_deinit((me_device_t *) me8200_device);
 158                        kfree(me8200_device);
 159                        PERROR("Cannot get memory for subdevice.\n");
 160                        return NULL;
 161                }
 162
 163                me_slist_add_subdevice_tail(&me8200_device->base.slist,
 164                                            subdevice);
 165        }
 166
 167        return (me_device_t *) me8200_device;
 168}
 169
 170// Init and exit of module.
 171
 172static int __init me8200_init(void)
 173{
 174        PDEBUG("executed.\n.");
 175        return 0;
 176}
 177
 178static void __exit me8200_exit(void)
 179{
 180        PDEBUG("executed.\n.");
 181}
 182
 183module_init(me8200_init);
 184
 185module_exit(me8200_exit);
 186
 187// Administrative stuff for modinfo.
 188MODULE_AUTHOR("Guenter Gebhardt <g.gebhardt@meilhaus.de>");
 189MODULE_DESCRIPTION("Device Driver Module for Template Device");
 190MODULE_SUPPORTED_DEVICE("Meilhaus Template Devices");
 191MODULE_LICENSE("GPL");
 192
 193// Export the constructor.
 194EXPORT_SYMBOL(me8200_pci_constructor);
 195
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.