linux/drivers/staging/meilhaus/me0900_device.c
<<
>>
Prefs
   1/**
   2 * @file me0900_device.c
   3 *
   4 * @brief ME-9x 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 "me0900_device.h"
  49#include "me0900_reg.h"
  50#include "mesubdevice.h"
  51#include "me0900_do.h"
  52#include "me0900_di.h"
  53
  54me_device_t *me0900_pci_constructor(struct pci_dev *pci_device)
  55{
  56        me0900_device_t *me0900_device;
  57        me_subdevice_t *subdevice;
  58        unsigned int version_idx;
  59        int err;
  60        int i;
  61        int port_shift;
  62
  63        PDEBUG("executed.\n");
  64
  65        // Allocate structure for device instance.
  66        me0900_device = kmalloc(sizeof(me0900_device_t), GFP_KERNEL);
  67
  68        if (!me0900_device) {
  69                PERROR("Cannot get memory for device instance.\n");
  70                return NULL;
  71        }
  72
  73        memset(me0900_device, 0, sizeof(me0900_device_t));
  74
  75        // Initialize base class structure.
  76        err = me_device_pci_init((me_device_t *) me0900_device, pci_device);
  77
  78        if (err) {
  79                kfree(me0900_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            me0900_versions_get_device_index(me0900_device->base.info.pci.
  87                                             device_id);
  88
  89        /* Initialize 8255 chip to desired mode */
  90        if (me0900_device->base.info.pci.device_id ==
  91            PCI_DEVICE_ID_MEILHAUS_ME0940) {
  92                outb(0x9B,
  93                     me0900_device->base.info.pci.reg_bases[2] +
  94                     ME0900_CTRL_REG);
  95        } else if (me0900_device->base.info.pci.device_id ==
  96                   PCI_DEVICE_ID_MEILHAUS_ME0950) {
  97                outb(0x89,
  98                     me0900_device->base.info.pci.reg_bases[2] +
  99                     ME0900_CTRL_REG);
 100                outb(0x00,
 101                     me0900_device->base.info.pci.reg_bases[2] +
 102                     ME0900_WRITE_ENABLE_REG);
 103        } else if (me0900_device->base.info.pci.device_id ==
 104                   PCI_DEVICE_ID_MEILHAUS_ME0960) {
 105                outb(0x8B,
 106                     me0900_device->base.info.pci.reg_bases[2] +
 107                     ME0900_CTRL_REG);
 108                outb(0x00,
 109                     me0900_device->base.info.pci.reg_bases[2] +
 110                     ME0900_WRITE_ENABLE_REG);
 111        }
 112
 113        port_shift =
 114            (me0900_device->base.info.pci.device_id ==
 115             PCI_DEVICE_ID_MEILHAUS_ME0960) ? 1 : 0;
 116        // Create subdevice instances.
 117
 118        for (i = 0; i < me0900_versions[version_idx].di_subdevices; i++) {
 119                subdevice =
 120                    (me_subdevice_t *) me0900_di_constructor(me0900_device->
 121                                                             base.info.pci.
 122                                                             reg_bases[2],
 123                                                             i + port_shift);
 124
 125                if (!subdevice) {
 126                        me_device_deinit((me_device_t *) me0900_device);
 127                        kfree(me0900_device);
 128                        PERROR("Cannot get memory for subdevice.\n");
 129                        return NULL;
 130                }
 131
 132                me_slist_add_subdevice_tail(&me0900_device->base.slist,
 133                                            subdevice);
 134        }
 135
 136        for (i = 0; i < me0900_versions[version_idx].do_subdevices; i++) {
 137                subdevice =
 138                    (me_subdevice_t *) me0900_do_constructor(me0900_device->
 139                                                             base.info.pci.
 140                                                             reg_bases[2], i);
 141
 142                if (!subdevice) {
 143                        me_device_deinit((me_device_t *) me0900_device);
 144                        kfree(me0900_device);
 145                        PERROR("Cannot get memory for subdevice.\n");
 146                        return NULL;
 147                }
 148
 149                me_slist_add_subdevice_tail(&me0900_device->base.slist,
 150                                            subdevice);
 151        }
 152
 153        return (me_device_t *) me0900_device;
 154}
 155
 156// Init and exit of module.
 157
 158static int __init me0900_init(void)
 159{
 160        PDEBUG("executed.\n.");
 161        return 0;
 162}
 163
 164static void __exit me0900_exit(void)
 165{
 166        PDEBUG("executed.\n.");
 167}
 168
 169module_init(me0900_init);
 170module_exit(me0900_exit);
 171
 172// Administrative stuff for modinfo.
 173MODULE_AUTHOR
 174    ("Guenter Gebhardt <g.gebhardt@meilhaus.de> & Krzysztof Gantzke <k.gantzke@meilhaus.de>");
 175MODULE_DESCRIPTION("Device Driver Module for ME-9x Device");
 176MODULE_SUPPORTED_DEVICE("Meilhaus ME-9x Devices");
 177MODULE_LICENSE("GPL");
 178
 179// Export the constructor.
 180EXPORT_SYMBOL(me0900_pci_constructor);
 181
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.