linux/drivers/staging/meilhaus/memain.c
<<
>>
Prefs
   1/**
   2 * @file memain.c
   3 *
   4 * @brief Main Meilhaus device driver.
   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#include <linux/pci.h>
  38//#include <linux/usb.h>
  39#include <linux/errno.h>
  40#include <asm/uaccess.h>
  41#include <linux/cdev.h>
  42#include <linux/rwsem.h>
  43
  44#include "medefines.h"
  45#include "metypes.h"
  46#include "meerror.h"
  47
  48#include "medebug.h"
  49#include "memain.h"
  50#include "medevice.h"
  51#include "meioctl.h"
  52#include "mecommon.h"
  53
  54/* Module parameters
  55*/
  56
  57#ifdef BOSCH
  58static unsigned int me_bosch_fw = 0;
  59
  60# ifdef module_param
  61module_param(me_bosch_fw, int, S_IRUGO);
  62# else
  63MODULE_PARM(me_bosch_fw, "i");
  64# endif
  65
  66MODULE_PARM_DESC(me_bosch_fw,
  67                 "Flags which signals the ME-4600 driver to load the bosch firmware (default = 0).");
  68#endif //BOSCH
  69
  70static unsigned int major = 0;
  71#ifdef module_param
  72module_param(major, int, S_IRUGO);
  73#else
  74MODULE_PARM(major, "i");
  75#endif
  76
  77/* Global Driver Lock
  78*/
  79
  80static struct file *me_filep = NULL;
  81static int me_count = 0;
  82static spinlock_t me_lock = SPIN_LOCK_UNLOCKED;
  83static DECLARE_RWSEM(me_rwsem);
  84
  85/* Board instances are kept in a global list */
  86LIST_HEAD(me_device_list);
  87
  88/* Prototypes
  89*/
  90
  91static int me_probe_pci(struct pci_dev *dev, const struct pci_device_id *id);
  92static void me_remove_pci(struct pci_dev *dev);
  93static int insert_to_device_list(me_device_t * n_device);
  94static int replace_with_dummy(int vendor_id, int device_id, int serial_no);
  95static void clear_device_list(void);
  96static int me_open(struct inode *inode_ptr, struct file *filep);
  97static int me_release(struct inode *, struct file *);
  98static int me_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
  99//static int me_probe_usb(struct usb_interface *interface, const struct usb_device_id *id);
 100//static void me_disconnect_usb(struct usb_interface *interface);
 101
 102/* Character device structure
 103*/
 104
 105static struct cdev *cdevp;
 106
 107/* File operations provided by the module
 108*/
 109
 110static struct file_operations me_file_operations = {
 111        .owner = THIS_MODULE,
 112        .ioctl = me_ioctl,
 113        .open = me_open,
 114        .release = me_release,
 115};
 116
 117struct pci_driver me_pci_driver = {
 118        .name = MEMAIN_NAME,
 119        .id_table = me_pci_table,
 120        .probe = me_probe_pci,
 121        .remove = me_remove_pci
 122};
 123
 124/* //me_usb_driver
 125static struct usb_driver me_usb_driver =
 126{
 127        .name = MEMAIN_NAME,
 128        .id_table = me_usb_table,
 129        .probe = me_probe_usb,
 130        .disconnect = me_disconnect_usb
 131};
 132*/
 133
 134#ifdef ME_LOCK_MULTIPLEX_TEMPLATE
 135ME_LOCK_MULTIPLEX_TEMPLATE("me_lock_device",
 136                           me_lock_device_t,
 137                           me_lock_device,
 138                           me_device_lock_device,
 139                           (device, filep, karg.lock, karg.flags))
 140
 141    ME_LOCK_MULTIPLEX_TEMPLATE("me_lock_subdevice",
 142                           me_lock_subdevice_t,
 143                           me_lock_subdevice,
 144                           me_device_lock_subdevice,
 145                           (device, filep, karg.subdevice, karg.lock,
 146                        karg.flags))
 147#else
 148#error macro ME_LOCK_MULTIPLEX_TEMPLATE not defined
 149#endif
 150
 151#ifdef ME_IO_MULTIPLEX_TEMPLATE
 152ME_IO_MULTIPLEX_TEMPLATE("me_io_irq_start",
 153                         me_io_irq_start_t,
 154                         me_io_irq_start,
 155                         me_device_io_irq_start,
 156                         (device,
 157                          filep,
 158                          karg.subdevice,
 159                          karg.channel,
 160                          karg.irq_source,
 161                          karg.irq_edge, karg.irq_arg, karg.flags))
 162
 163    ME_IO_MULTIPLEX_TEMPLATE("me_io_irq_wait",
 164                         me_io_irq_wait_t,
 165                         me_io_irq_wait,
 166                         me_device_io_irq_wait,
 167                         (device,
 168                      filep,
 169                      karg.subdevice,
 170                      karg.channel,
 171                      &karg.irq_count, &karg.value, karg.time_out, karg.flags))
 172
 173    ME_IO_MULTIPLEX_TEMPLATE("me_io_irq_stop",
 174                         me_io_irq_stop_t,
 175                         me_io_irq_stop,
 176                         me_device_io_irq_stop,
 177                         (device,
 178                      filep, karg.subdevice, karg.channel, karg.flags))
 179
 180    ME_IO_MULTIPLEX_TEMPLATE("me_io_reset_device",
 181                         me_io_reset_device_t,
 182                         me_io_reset_device,
 183                         me_device_io_reset_device, (device, filep, karg.flags))
 184
 185    ME_IO_MULTIPLEX_TEMPLATE("me_io_reset_subdevice",
 186                         me_io_reset_subdevice_t,
 187                         me_io_reset_subdevice,
 188                         me_device_io_reset_subdevice,
 189                         (device, filep, karg.subdevice, karg.flags))
 190
 191    ME_IO_MULTIPLEX_TEMPLATE("me_io_single_config",
 192                         me_io_single_config_t,
 193                         me_io_single_config,
 194                         me_device_io_single_config,
 195                         (device,
 196                      filep,
 197                      karg.subdevice,
 198                      karg.channel,
 199                      karg.single_config,
 200                      karg.ref,
 201                      karg.trig_chan,
 202                      karg.trig_type, karg.trig_edge, karg.flags))
 203
 204    ME_IO_MULTIPLEX_TEMPLATE("me_io_stream_new_values",
 205                         me_io_stream_new_values_t,
 206                         me_io_stream_new_values,
 207                         me_device_io_stream_new_values,
 208                         (device,
 209                      filep,
 210                      karg.subdevice, karg.time_out, &karg.count, karg.flags))
 211
 212    ME_IO_MULTIPLEX_TEMPLATE("me_io_stream_read",
 213                         me_io_stream_read_t,
 214                         me_io_stream_read,
 215                         me_device_io_stream_read,
 216                         (device,
 217                      filep,
 218                      karg.subdevice,
 219                      karg.read_mode, karg.values, &karg.count, karg.flags))
 220
 221    ME_IO_MULTIPLEX_TEMPLATE("me_io_stream_status",
 222                         me_io_stream_status_t,
 223                         me_io_stream_status,
 224                         me_device_io_stream_status,
 225                         (device,
 226                      filep,
 227                      karg.subdevice,
 228                      karg.wait, &karg.status, &karg.count, karg.flags))
 229
 230    ME_IO_MULTIPLEX_TEMPLATE("me_io_stream_write",
 231                         me_io_stream_write_t,
 232                         me_io_stream_write,
 233                         me_device_io_stream_write,
 234                         (device,
 235                      filep,
 236                      karg.subdevice,
 237                      karg.write_mode, karg.values, &karg.count, karg.flags))
 238#else
 239#error macro ME_IO_MULTIPLEX_TEMPLATE not defined
 240#endif
 241
 242#ifdef ME_QUERY_MULTIPLEX_STR_TEMPLATE
 243ME_QUERY_MULTIPLEX_STR_TEMPLATE("me_query_name_device",
 244                                me_query_name_device_t,
 245                                me_query_name_device,
 246                                me_device_query_name_device, (device, &msg))
 247
 248    ME_QUERY_MULTIPLEX_STR_TEMPLATE("me_query_name_device_driver",
 249                                me_query_name_device_driver_t,
 250                                me_query_name_device_driver,
 251                                me_device_query_name_device_driver,
 252                                (device, &msg))
 253
 254    ME_QUERY_MULTIPLEX_STR_TEMPLATE("me_query_description_device",
 255                                me_query_description_device_t,
 256                                me_query_description_device,
 257                                me_device_query_description_device,
 258                                (device, &msg))
 259#else
 260#error macro ME_QUERY_MULTIPLEX_STR_TEMPLATE not defined
 261#endif
 262
 263#ifdef ME_QUERY_MULTIPLEX_TEMPLATE
 264ME_QUERY_MULTIPLEX_TEMPLATE("me_query_info_device",
 265                            me_query_info_device_t,
 266                            me_query_info_device,
 267                            me_device_query_info_device,
 268                            (device,
 269                             &karg.vendor_id,
 270                             &karg.device_id,
 271                             &karg.serial_no,
 272                             &karg.bus_type,
 273                             &karg.bus_no,
 274                             &karg.dev_no, &karg.func_no, &karg.plugged))
 275
 276    ME_QUERY_MULTIPLEX_TEMPLATE("me_query_number_subdevices",
 277                            me_query_number_subdevices_t,
 278                            me_query_number_subdevices,
 279                            me_device_query_number_subdevices,
 280                            (device, &karg.number))
 281
 282    ME_QUERY_MULTIPLEX_TEMPLATE("me_query_number_channels",
 283                            me_query_number_channels_t,
 284                            me_query_number_channels,
 285                            me_device_query_number_channels,
 286                            (device, karg.subdevice, &karg.number))
 287
 288    ME_QUERY_MULTIPLEX_TEMPLATE("me_query_subdevice_by_type",
 289                            me_query_subdevice_by_type_t,
 290                            me_query_subdevice_by_type,
 291                            me_device_query_subdevice_by_type,
 292                            (device,
 293                         karg.start_subdevice,
 294                         karg.type, karg.subtype, &karg.subdevice))
 295
 296    ME_QUERY_MULTIPLEX_TEMPLATE("me_query_subdevice_type",
 297                            me_query_subdevice_type_t,
 298                            me_query_subdevice_type,
 299                            me_device_query_subdevice_type,
 300                            (device, karg.subdevice, &karg.type, &karg.subtype))
 301
 302    ME_QUERY_MULTIPLEX_TEMPLATE("me_query_subdevice_caps",
 303                            me_query_subdevice_caps_t,
 304                            me_query_subdevice_caps,
 305                            me_device_query_subdevice_caps,
 306                            (device, karg.subdevice, &karg.caps))
 307
 308    ME_QUERY_MULTIPLEX_TEMPLATE("me_query_subdevice_caps_args",
 309                            me_query_subdevice_caps_args_t,
 310                            me_query_subdevice_caps_args,
 311                            me_device_query_subdevice_caps_args,
 312                            (device, karg.subdevice, karg.cap, karg.args,
 313                         karg.count))
 314
 315    ME_QUERY_MULTIPLEX_TEMPLATE("me_query_number_ranges",
 316                            me_query_number_ranges_t,
 317                            me_query_number_ranges,
 318                            me_device_query_number_ranges,
 319                            (device, karg.subdevice, karg.unit, &karg.number))
 320
 321    ME_QUERY_MULTIPLEX_TEMPLATE("me_query_range_by_min_max",
 322                            me_query_range_by_min_max_t,
 323                            me_query_range_by_min_max,
 324                            me_device_query_range_by_min_max,
 325                            (device,
 326                         karg.subdevice,
 327                         karg.unit,
 328                         &karg.min, &karg.max, &karg.max_data, &karg.range))
 329
 330    ME_QUERY_MULTIPLEX_TEMPLATE("me_query_range_info",
 331                            me_query_range_info_t,
 332                            me_query_range_info,
 333                            me_device_query_range_info,
 334                            (device,
 335                         karg.subdevice,
 336                         karg.range,
 337                         &karg.unit, &karg.min, &karg.max, &karg.max_data))
 338
 339    ME_QUERY_MULTIPLEX_TEMPLATE("me_query_timer",
 340                            me_query_timer_t,
 341                            me_query_timer,
 342                            me_device_query_timer,
 343                            (device,
 344                         karg.subdevice,
 345                         karg.timer,
 346                         &karg.base_frequency,
 347                         &karg.min_ticks, &karg.max_ticks))
 348
 349    ME_QUERY_MULTIPLEX_TEMPLATE("me_query_version_device_driver",
 350                            me_query_version_device_driver_t,
 351                            me_query_version_device_driver,
 352                            me_device_query_version_device_driver,
 353                            (device, &karg.version))
 354#else
 355#error macro ME_QUERY_MULTIPLEX_TEMPLATE not defined
 356#endif
 357
 358/** ******************************************************************************** **/
 359
 360static me_device_t *get_dummy_instance(unsigned short vendor_id,
 361                                       unsigned short device_id,
 362                                       unsigned int serial_no,
 363                                       int bus_type,
 364                                       int bus_no, int dev_no, int func_no)
 365{
 366        int err;
 367        me_dummy_constructor_t constructor = NULL;
 368        me_device_t *instance;
 369
 370        PDEBUG("executed.\n");
 371
 372        if ((constructor = symbol_get(medummy_constructor)) == NULL) {
 373                err = request_module(MEDUMMY_NAME);
 374
 375                if (err) {
 376                        PERROR("Error while request for module %s.\n",
 377                               MEDUMMY_NAME);
 378                        return NULL;
 379                }
 380
 381                if ((constructor = symbol_get(medummy_constructor)) == NULL) {
 382                        PERROR("Can't get %s driver module constructor.\n",
 383                               MEDUMMY_NAME);
 384                        return NULL;
 385                }
 386        }
 387
 388        if ((instance = (*constructor) (vendor_id,
 389                                        device_id,
 390                                        serial_no,
 391                                        bus_type,
 392                                        bus_no, dev_no, func_no)) == NULL)
 393                symbol_put(medummy_constructor);
 394
 395        return instance;
 396}
 397
 398static int me_probe_pci(struct pci_dev *dev, const struct pci_device_id *id)
 399{
 400        int err;
 401        me_pci_constructor_t constructor = NULL;
 402#ifdef BOSCH
 403        me_bosch_constructor_t constructor_bosch = NULL;
 404#endif
 405        me_device_t *n_device = NULL;
 406        uint32_t device;
 407
 408        char constructor_name[24] = "me0000_pci_constructor";
 409        char module_name[7] = "me0000";
 410
 411        PDEBUG("executed.\n");
 412        device = dev->device;
 413        if ((device & 0xF000) == 0x6000) {      // Exceptions: me61xx, me62xx, me63xx are handled by one driver.
 414                device &= 0xF0FF;
 415        }
 416
 417        constructor_name[2] += (char)((device >> 12) & 0x000F);
 418        constructor_name[3] += (char)((device >> 8) & 0x000F);
 419        PDEBUG("constructor_name: %s\n", constructor_name);
 420        module_name[2] += (char)((device >> 12) & 0x000F);
 421        module_name[3] += (char)((device >> 8) & 0x000F);
 422        PDEBUG("module_name: %s\n", module_name);
 423
 424        if ((constructor =
 425             (me_pci_constructor_t) symbol_get(constructor_name)) == NULL) {
 426                if (request_module(module_name)) {
 427                        PERROR("Error while request for module %s.\n",
 428                               module_name);
 429                        return -ENODEV;
 430                }
 431
 432                if ((constructor =
 433                     (me_pci_constructor_t) symbol_get(constructor_name)) ==
 434                    NULL) {
 435                        PERROR("Can't get %s driver module constructor.\n",
 436                               module_name);
 437                        return -ENODEV;
 438                }
 439        }
 440#ifdef BOSCH
 441        if ((device & 0xF000) == 0x4000) {      // Bosch build has differnt constructor for me4600.
 442                if ((n_device =
 443                     (*constructor_bosch) (dev, me_bosch_fw)) == NULL) {
 444                        symbol_put(constructor_name);
 445                        PERROR
 446                            ("Can't get device instance of %s driver module.\n",
 447                             module_name);
 448                        return -ENODEV;
 449                }
 450        } else {
 451#endif
 452                if ((n_device = (*constructor) (dev)) == NULL) {
 453                        symbol_put(constructor_name);
 454                        PERROR
 455                            ("Can't get device instance of %s driver module.\n",
 456                             module_name);
 457                        return -ENODEV;
 458                }
 459#ifdef BOSCH
 460        }
 461#endif
 462
 463        insert_to_device_list(n_device);
 464        err =
 465            n_device->me_device_io_reset_device(n_device, NULL,
 466                                                ME_IO_RESET_DEVICE_NO_FLAGS);
 467        if (err) {
 468                PERROR("Error while reseting device.\n");
 469        } else {
 470                PDEBUG("Reseting device was sucessful.\n");
 471        }
 472        return ME_ERRNO_SUCCESS;
 473}
 474
 475static void release_instance(me_device_t * device)
 476{
 477        int vendor_id;
 478        int device_id;
 479        int serial_no;
 480        int bus_type;
 481        int bus_no;
 482        int dev_no;
 483        int func_no;
 484        int plugged;
 485
 486        uint32_t dev_id;
 487
 488        char constructor_name[24] = "me0000_pci_constructor";
 489
 490        PDEBUG("executed.\n");
 491
 492        device->me_device_query_info_device(device,
 493                                            &vendor_id,
 494                                            &device_id,
 495                                            &serial_no,
 496                                            &bus_type,
 497                                            &bus_no,
 498                                            &dev_no, &func_no, &plugged);
 499
 500        dev_id = device_id;
 501        device->me_device_destructor(device);
 502
 503        if (plugged != ME_PLUGGED_IN) {
 504                PDEBUG("release: medummy_constructor\n");
 505
 506                symbol_put("medummy_constructor");
 507        } else {
 508                if ((dev_id & 0xF000) == 0x6000) {      // Exceptions: me61xx, me62xx, me63xx are handled by one driver.
 509                        dev_id &= 0xF0FF;
 510                }
 511
 512                constructor_name[2] += (char)((dev_id >> 12) & 0x000F);
 513                constructor_name[3] += (char)((dev_id >> 8) & 0x000F);
 514                PDEBUG("release: %s\n", constructor_name);
 515
 516                symbol_put(constructor_name);
 517        }
 518}
 519
 520static int insert_to_device_list(me_device_t * n_device)
 521{
 522        me_device_t *o_device = NULL;
 523
 524        struct list_head *pos;
 525        int n_vendor_id;
 526        int n_device_id;
 527        int n_serial_no;
 528        int n_bus_type;
 529        int n_bus_no;
 530        int n_dev_no;
 531        int n_func_no;
 532        int n_plugged;
 533        int o_vendor_id;
 534        int o_device_id;
 535        int o_serial_no;
 536        int o_bus_type;
 537        int o_bus_no;
 538        int o_dev_no;
 539        int o_func_no;
 540        int o_plugged;
 541
 542        PDEBUG("executed.\n");
 543
 544        n_device->me_device_query_info_device(n_device,
 545                                              &n_vendor_id,
 546                                              &n_device_id,
 547                                              &n_serial_no,
 548                                              &n_bus_type,
 549                                              &n_bus_no,
 550                                              &n_dev_no,
 551                                              &n_func_no, &n_plugged);
 552
 553        down_write(&me_rwsem);
 554
 555        list_for_each(pos, &me_device_list) {
 556                o_device = list_entry(pos, me_device_t, list);
 557                o_device->me_device_query_info_device(o_device,
 558                                                      &o_vendor_id,
 559                                                      &o_device_id,
 560                                                      &o_serial_no,
 561                                                      &o_bus_type,
 562                                                      &o_bus_no,
 563                                                      &o_dev_no,
 564                                                      &o_func_no, &o_plugged);
 565
 566                if (o_plugged == ME_PLUGGED_OUT) {
 567                        if (((o_vendor_id == n_vendor_id) &&
 568                             (o_device_id == n_device_id) &&
 569                             (o_serial_no == n_serial_no) &&
 570                             (o_bus_type == n_bus_type)) ||
 571                            ((o_vendor_id == n_vendor_id) &&
 572                             (o_device_id == n_device_id) &&
 573                             (o_bus_type == n_bus_type) &&
 574                             (o_bus_no == n_bus_no) &&
 575                             (o_dev_no == n_dev_no) &&
 576                             (o_func_no == n_func_no))) {
 577                                n_device->list.prev = pos->prev;
 578                                n_device->list.next = pos->next;
 579                                pos->prev->next = &n_device->list;
 580                                pos->next->prev = &n_device->list;
 581                                release_instance(o_device);
 582                                break;
 583                        }
 584                }
 585        }
 586
 587        if (pos == &me_device_list) {
 588                list_add_tail(&n_device->list, &me_device_list);
 589        }
 590
 591        up_write(&me_rwsem);
 592
 593        return 0;
 594}
 595
 596static void me_remove_pci(struct pci_dev *dev)
 597{
 598        int vendor_id = dev->vendor;
 599        int device_id = dev->device;
 600        int subsystem_vendor = dev->subsystem_vendor;
 601        int subsystem_device = dev->subsystem_device;
 602        int serial_no = (subsystem_device << 16) | subsystem_vendor;
 603
 604        PDEBUG("executed.\n");
 605
 606        PINFO("Vendor id = 0x%08X\n", vendor_id);
 607        PINFO("Device id = 0x%08X\n", device_id);
 608        PINFO("Serial Number = 0x%08X\n", serial_no);
 609
 610        replace_with_dummy(vendor_id, device_id, serial_no);
 611}
 612
 613static int replace_with_dummy(int vendor_id, int device_id, int serial_no)
 614{
 615
 616        struct list_head *pos;
 617        me_device_t *n_device = NULL;
 618        me_device_t *o_device = NULL;
 619        int o_vendor_id;
 620        int o_device_id;
 621        int o_serial_no;
 622        int o_bus_type;
 623        int o_bus_no;
 624        int o_dev_no;
 625        int o_func_no;
 626        int o_plugged;
 627
 628        PDEBUG("executed.\n");
 629
 630        down_write(&me_rwsem);
 631
 632        list_for_each(pos, &me_device_list) {
 633                o_device = list_entry(pos, me_device_t, list);
 634                o_device->me_device_query_info_device(o_device,
 635                                                      &o_vendor_id,
 636                                                      &o_device_id,
 637                                                      &o_serial_no,
 638                                                      &o_bus_type,
 639                                                      &o_bus_no,
 640                                                      &o_dev_no,
 641                                                      &o_func_no, &o_plugged);
 642
 643                if (o_plugged == ME_PLUGGED_IN) {
 644                        if (((o_vendor_id == vendor_id) &&
 645                             (o_device_id == device_id) &&
 646                             (o_serial_no == serial_no))) {
 647                                n_device = get_dummy_instance(o_vendor_id,
 648                                                              o_device_id,
 649                                                              o_serial_no,
 650                                                              o_bus_type,
 651                                                              o_bus_no,
 652                                                              o_dev_no,
 653                                                              o_func_no);
 654
 655                                if (!n_device) {
 656                                        up_write(&me_rwsem);
 657                                        PERROR("Cannot get dummy instance.\n");
 658                                        return 1;
 659                                }
 660
 661                                n_device->list.prev = pos->prev;
 662
 663                                n_device->list.next = pos->next;
 664                                pos->prev->next = &n_device->list;
 665                                pos->next->prev = &n_device->list;
 666                                release_instance(o_device);
 667                                break;
 668                        }
 669                }
 670        }
 671
 672        up_write(&me_rwsem);
 673
 674        return 0;
 675}
 676
 677static void clear_device_list(void)
 678{
 679
 680        struct list_head *entry;
 681        me_device_t *device;
 682
 683        // Clear the device info list .
 684        down_write(&me_rwsem);
 685
 686        while (!list_empty(&me_device_list)) {
 687                entry = me_device_list.next;
 688                device = list_entry(entry, me_device_t, list);
 689                list_del(entry);
 690                release_instance(device);
 691        }
 692
 693        up_write(&me_rwsem);
 694}
 695
 696static int lock_driver(struct file *filep, int lock, int flags)
 697{
 698        int err = ME_ERRNO_SUCCESS;
 699        me_device_t *device;
 700
 701        PDEBUG("executed.\n");
 702
 703        down_read(&me_rwsem);
 704
 705        spin_lock(&me_lock);
 706
 707        switch (lock) {
 708
 709        case ME_LOCK_SET:
 710                if (me_count) {
 711                        PERROR
 712                            ("Driver System is currently used by another process.\n");
 713                        err = ME_ERRNO_USED;
 714                } else if ((me_filep != NULL) && (me_filep != filep)) {
 715                        PERROR
 716                            ("Driver System is already logged by another process.\n");
 717                        err = ME_ERRNO_LOCKED;
 718                } else {
 719                        list_for_each_entry(device, &me_device_list, list) {
 720                                err =
 721                                    device->me_device_lock_device(device, filep,
 722                                                                  ME_LOCK_CHECK,
 723                                                                  flags);
 724
 725                                if (err)
 726                                        break;
 727                        }
 728
 729                        if (!err)
 730                                me_filep = filep;
 731                }
 732
 733                break;
 734
 735        case ME_LOCK_RELEASE:
 736                if ((me_filep != NULL) && (me_filep != filep)) {
 737                        err = ME_ERRNO_SUCCESS;
 738                } else {
 739                        list_for_each_entry(device, &me_device_list, list) {
 740                                device->me_device_lock_device(device, filep,
 741                                                              ME_LOCK_RELEASE,
 742                                                              flags);
 743                        }
 744
 745                        me_filep = NULL;
 746                }
 747
 748                break;
 749
 750        default:
 751                PERROR("Invalid lock specified.\n");
 752
 753                err = ME_ERRNO_INVALID_LOCK;
 754
 755                break;
 756        }
 757
 758        spin_unlock(&me_lock);
 759
 760        up_read(&me_rwsem);
 761
 762        return err;
 763}
 764
 765static int me_lock_driver(struct file *filep, me_lock_driver_t * arg)
 766{
 767        int err = 0;
 768
 769        me_lock_driver_t lock;
 770
 771        PDEBUG("executed.\n");
 772
 773        err = copy_from_user(&lock, arg, sizeof(me_lock_driver_t));
 774
 775        if (err) {
 776                PERROR("Can't copy arguments to kernel space.\n");
 777                return -EFAULT;
 778        }
 779
 780        lock.errno = lock_driver(filep, lock.lock, lock.flags);
 781
 782        err = copy_to_user(arg, &lock, sizeof(me_lock_driver_t));
 783
 784        if (err) {
 785                PERROR("Can't copy query back to user space.\n");
 786                return -EFAULT;
 787        }
 788
 789        return ME_ERRNO_SUCCESS;
 790}
 791
 792static int me_open(struct inode *inode_ptr, struct file *filep)
 793{
 794
 795        PDEBUG("executed.\n");
 796        // Nothing to do here.
 797        return 0;
 798}
 799
 800static int me_release(struct inode *inode_ptr, struct file *filep)
 801{
 802
 803        PDEBUG("executed.\n");
 804        lock_driver(filep, ME_LOCK_RELEASE, ME_LOCK_DRIVER_NO_FLAGS);
 805
 806        return 0;
 807}
 808
 809static int me_query_version_main_driver(struct file *filep,
 810                                        me_query_version_main_driver_t * arg)
 811{
 812        int err;
 813        me_query_version_main_driver_t karg;
 814
 815        PDEBUG("executed.\n");
 816
 817        karg.version = ME_VERSION_DRIVER;
 818        karg.errno = ME_ERRNO_SUCCESS;
 819
 820        err = copy_to_user(arg, &karg, sizeof(me_query_version_main_driver_t));
 821
 822        if (err) {
 823                PERROR("Can't copy query back to user space.\n");
 824                return -EFAULT;
 825        }
 826
 827        return 0;
 828}
 829
 830static int me_config_load_device(struct file *filep,
 831                                 me_cfg_device_entry_t * karg, int device_no)
 832{
 833
 834        int err = ME_ERRNO_SUCCESS;
 835        int k = 0;
 836
 837        struct list_head *pos = NULL;
 838        me_device_t *device = NULL;
 839
 840        PDEBUG("executed.\n");
 841
 842        list_for_each(pos, &me_device_list) {
 843                if (k == device_no) {
 844                        device = list_entry(pos, me_device_t, list);
 845                        break;
 846                }
 847
 848                k++;
 849        }
 850
 851        if (pos == &me_device_list) {
 852                PERROR("Invalid device number specified.\n");
 853                return ME_ERRNO_INVALID_DEVICE;
 854        } else {
 855                spin_lock(&me_lock);
 856
 857                if ((me_filep != NULL) && (me_filep != filep)) {
 858                        spin_unlock(&me_lock);
 859                        PERROR("Resource is locked by another process.\n");
 860                        return ME_ERRNO_LOCKED;
 861                } else {
 862                        me_count++;
 863                        spin_unlock(&me_lock);
 864
 865                        err =
 866                            device->me_device_config_load(device, filep, karg);
 867
 868                        spin_lock(&me_lock);
 869                        me_count--;
 870                        spin_unlock(&me_lock);
 871                }
 872        }
 873
 874        return err;
 875}
 876
 877static int me_config_load(struct file *filep, me_config_load_t * arg)
 878{
 879        int err;
 880        int i;
 881        me_config_load_t cfg_setup;
 882        me_config_load_t karg_cfg_setup;
 883
 884        struct list_head *pos = NULL;
 885
 886        struct list_head new_list;
 887        me_device_t *o_device;
 888        me_device_t *n_device;
 889        int o_vendor_id;
 890        int o_device_id;
 891        int o_serial_no;
 892        int o_bus_type;
 893        int o_bus_no;
 894        int o_dev_no;
 895        int o_func_no;
 896        int o_plugged;
 897
 898        PDEBUG("executed.\n");
 899
 900        // Copy argument to kernel space.
 901        err = copy_from_user(&karg_cfg_setup, arg, sizeof(me_config_load_t));
 902
 903        if (err) {
 904                PERROR("Can't copy arguments to kernel space.\n");
 905                return -EFAULT;
 906        }
 907        // Allocate kernel buffer for device list.
 908        cfg_setup.device_list =
 909            kmalloc(sizeof(me_cfg_device_entry_t) * karg_cfg_setup.count,
 910                    GFP_KERNEL);
 911
 912        if (!cfg_setup.device_list) {
 913                PERROR("Can't get buffer %li for device list.\n",
 914                       sizeof(me_cfg_device_entry_t) * karg_cfg_setup.count);
 915                return -ENOMEM;
 916        }
 917        // Copy device list to kernel space.
 918        err =
 919            copy_from_user(cfg_setup.device_list, karg_cfg_setup.device_list,
 920                           sizeof(me_cfg_device_entry_t) *
 921                           karg_cfg_setup.count);
 922
 923        if (err) {
 924                PERROR("Can't copy device list to kernel space.\n");
 925                kfree(cfg_setup.device_list);
 926                return -EFAULT;
 927        }
 928
 929        cfg_setup.count = karg_cfg_setup.count;
 930
 931        INIT_LIST_HEAD(&new_list);
 932
 933        down_write(&me_rwsem);
 934
 935        spin_lock(&me_lock);
 936
 937        if ((me_filep != NULL) && (me_filep != filep)) {
 938                spin_unlock(&me_lock);
 939                PERROR("Driver System is logged by another process.\n");
 940                karg_cfg_setup.errno = ME_ERRNO_LOCKED;
 941        } else {
 942                me_count++;
 943                spin_unlock(&me_lock);
 944
 945                for (i = 0; i < karg_cfg_setup.count; i++) {
 946                        PDEBUG("me_config_load() device=%d.\n", i);
 947                        if (cfg_setup.device_list[i].tcpip.access_type ==
 948                            ME_ACCESS_TYPE_LOCAL) {
 949                                list_for_each(pos, &me_device_list) {
 950                                        o_device =
 951                                            list_entry(pos, me_device_t, list);
 952                                        o_device->
 953                                            me_device_query_info_device
 954                                            (o_device, &o_vendor_id,
 955                                             &o_device_id, &o_serial_no,
 956                                             &o_bus_type, &o_bus_no, &o_dev_no,
 957                                             &o_func_no, &o_plugged);
 958
 959                                        if (cfg_setup.device_list[i].info.
 960                                            hw_location.bus_type ==
 961                                            ME_BUS_TYPE_PCI) {
 962                                                if (((o_vendor_id ==
 963                                                      cfg_setup.device_list[i].
 964                                                      info.vendor_id)
 965                                                     && (o_device_id ==
 966                                                         cfg_setup.
 967                                                         device_list[i].info.
 968                                                         device_id)
 969                                                     && (o_serial_no ==
 970                                                         cfg_setup.
 971                                                         device_list[i].info.
 972                                                         serial_no)
 973                                                     && (o_bus_type ==
 974                                                         cfg_setup.
 975                                                         device_list[i].info.
 976                                                         hw_location.bus_type))
 977                                                    ||
 978                                                    ((o_vendor_id ==
 979                                                      cfg_setup.device_list[i].
 980                                                      info.vendor_id)
 981                                                     && (o_device_id ==
 982                                                         cfg_setup.
 983                                                         device_list[i].info.
 984                                                         device_id)
 985                                                     && (o_bus_type ==
 986                                                         cfg_setup.
 987                                                         device_list[i].info.
 988                                                         hw_location.bus_type)
 989                                                     && (o_bus_no ==
 990                                                         cfg_setup.
 991                                                         device_list[i].info.
 992                                                         hw_location.pci.bus_no)
 993                                                     && (o_dev_no ==
 994                                                         cfg_setup.
 995                                                         device_list[i].info.
 996                                                         hw_location.pci.
 997                                                         device_no)
 998                                                     && (o_func_no ==
 999                                                         cfg_setup.
1000                                                         device_list[i].info.
1001                                                         hw_location.pci.
1002                                                         function_no))) {
1003                                                        list_move_tail(pos,
1004                                                                       &new_list);
1005                                                        break;
1006                                                }
1007                                        }
1008/*
1009                                        else if (cfg_setup.device_list[i].info.hw_location.bus_type == ME_BUS_TYPE_USB)
1010                                        {
1011                                                if (((o_vendor_id == cfg_setup.device_list[i].info.vendor_id) &&
1012                                                        (o_device_id == cfg_setup.device_list[i].info.device_id) &&
1013                                                        (o_serial_no == cfg_setup.device_list[i].info.serial_no) &&
1014                                                        (o_bus_type == cfg_setup.device_list[i].info.hw_location.bus_type)) ||
1015                                                        ((o_vendor_id == cfg_setup.device_list[i].info.vendor_id) &&
1016                                                         (o_device_id == cfg_setup.device_list[i].info.device_id) &&
1017                                                         (o_bus_type == cfg_setup.device_list[i].info.hw_location.bus_type) &&
1018                                                         (o_bus_no == cfg_setup.device_list[i].info.hw_location.usb.root_hub_no)))
1019                                                {
1020                                                        list_move_tail(pos, &new_list);
1021                                                        break;
1022                                                }
1023                                        }
1024*/
1025                                        else {
1026                                                PERROR("Wrong bus type: %d.\n",
1027                                                       cfg_setup.device_list[i].
1028                                                       info.hw_location.
1029                                                       bus_type);
1030                                        }
1031                                }
1032
1033                                if (pos == &me_device_list) {   // Device is not already in the list
1034                                        if (cfg_setup.device_list[i].info.
1035                                            hw_location.bus_type ==
1036                                            ME_BUS_TYPE_PCI) {
1037                                                n_device =
1038                                                    get_dummy_instance
1039                                                    (cfg_setup.device_list[i].
1040                                                     info.vendor_id,
1041                                                     cfg_setup.device_list[i].
1042                                                     info.device_id,
1043                                                     cfg_setup.device_list[i].
1044                                                     info.serial_no,
1045                                                     cfg_setup.device_list[i].
1046                                                     info.hw_location.bus_type,
1047                                                     cfg_setup.device_list[i].
1048                                                     info.hw_location.pci.
1049                                                     bus_no,
1050                                                     cfg_setup.device_list[i].
1051                                                     info.hw_location.pci.
1052                                                     device_no,
1053                                                     cfg_setup.device_list[i].
1054                                                     info.hw_location.pci.
1055                                                     function_no);
1056
1057                                                if (!n_device) {
1058                                                        PERROR
1059                                                            ("Can't get dummy instance.\n");
1060                                                        kfree(cfg_setup.
1061                                                              device_list);
1062                                                        spin_lock(&me_lock);
1063                                                        me_count--;
1064                                                        spin_unlock(&me_lock);
1065                                                        up_write(&me_rwsem);
1066                                                        return -EFAULT;
1067                                                }
1068
1069                                                list_add_tail(&n_device->list,
1070                                                              &new_list);
1071                                        }
1072/*
1073                                        else if (cfg_setup.device_list[i].info.hw_location.bus_type == ME_BUS_TYPE_USB)
1074                                        {
1075                                                n_device = get_dummy_instance(
1076                                                               cfg_setup.device_list[i].info.vendor_id,
1077                                                               cfg_setup.device_list[i].info.device_id,
1078                                                               cfg_setup.device_list[i].info.serial_no,
1079                                                               cfg_setup.device_list[i].info.hw_location.bus_type,
1080                                                               cfg_setup.device_list[i].info.hw_location.usb.root_hub_no,
1081                                                               0,
1082                                                               0);
1083
1084                                                if (!n_device)
1085                                                {
1086                                                        PERROR("Can't get dummy instance.\n");
1087                                                        kfree(cfg_setup.device_list);
1088                                                        spin_lock(&me_lock);
1089                                                        me_count--;
1090                                                        spin_unlock(&me_lock);
1091                                                        up_write(&me_rwsem);
1092                                                        return -EFAULT;
1093                                                }
1094
1095                                                list_add_tail(&n_device->list, &new_list);
1096                                        }
1097*/
1098                                }
1099                        } else {
1100                                n_device = get_dummy_instance(0,
1101                                                              0, 0, 0, 0, 0, 0);
1102
1103                                if (!n_device) {
1104                                        PERROR("Can't get dummy instance.\n");
1105                                        kfree(cfg_setup.device_list);
1106                                        spin_lock(&me_lock);
1107                                        me_count--;
1108                                        spin_unlock(&me_lock);
1109                                        up_write(&me_rwsem);
1110                                        return -EFAULT;
1111                                }
1112
1113                                list_add_tail(&n_device->list, &new_list);
1114                        }
1115                }
1116
1117                while (!list_empty(&me_device_list)) {
1118                        o_device =
1119                            list_entry(me_device_list.next, me_device_t, list);
1120                        o_device->me_device_query_info_device(o_device,
1121                                                              &o_vendor_id,
1122                                                              &o_device_id,
1123                                                              &o_serial_no,
1124                                                              &o_bus_type,
1125                                                              &o_bus_no,
1126                                                              &o_dev_no,
1127                                                              &o_func_no,
1128                                                              &o_plugged);
1129
1130                        if (o_plugged == ME_PLUGGED_IN) {
1131                                list_move_tail(me_device_list.next, &new_list);
1132                        } else {
1133                                list_del(me_device_list.next);
1134                                release_instance(o_device);
1135                        }
1136                }
1137
1138                // Move temporary new list to global driver list.
1139                list_splice(&new_list, &me_device_list);
1140
1141                karg_cfg_setup.errno = ME_ERRNO_SUCCESS;
1142        }
1143
1144        for (i = 0; i < cfg_setup.count; i++) {
1145
1146                karg_cfg_setup.errno =
1147                    me_config_load_device(filep, &cfg_setup.device_list[i], i);
1148                if (karg_cfg_setup.errno) {
1149                        PERROR("me_config_load_device(%d)=%d\n", i,
1150                               karg_cfg_setup.errno);
1151                        break;
1152                }
1153        }
1154
1155        spin_lock(&me_lock);
1156
1157        me_count--;
1158        spin_unlock(&me_lock);
1159        up_write(&me_rwsem);
1160
1161        err = copy_to_user(arg, &karg_cfg_setup, sizeof(me_config_load_t));
1162
1163        if (err) {
1164                PERROR("Can't copy config list to user space.\n");
1165                kfree(cfg_setup.device_list);
1166                return -EFAULT;
1167        }
1168
1169        kfree(cfg_setup.device_list);
1170        return 0;
1171}
1172
1173static int me_io_stream_start(struct file *filep, me_io_stream_start_t * arg)
1174{
1175        int err;
1176        int i, k;
1177
1178        struct list_head *pos;
1179        me_device_t *device;
1180        me_io_stream_start_t karg;
1181        meIOStreamStart_t *list;
1182
1183        PDEBUG("executed.\n");
1184
1185        err = copy_from_user(&karg, arg, sizeof(me_io_stream_start_t));
1186
1187        if (err) {
1188                PERROR("Can't copy arguments to kernel space.\n");
1189                return -EFAULT;
1190        }
1191
1192        karg.errno = ME_ERRNO_SUCCESS;
1193
1194        list = kmalloc(sizeof(meIOStreamStart_t) * karg.count, GFP_KERNEL);
1195
1196        if (!list) {
1197                PERROR("Can't get buffer for start list.\n");
1198                return -ENOMEM;
1199        }
1200
1201        err =
1202            copy_from_user(list, karg.start_list,
1203                           sizeof(meIOStreamStart_t) * karg.count);
1204
1205        if (err) {
1206                PERROR("Can't copy start list to kernel space.\n");
1207                kfree(list);
1208                return -EFAULT;
1209        }
1210
1211        spin_lock(&me_lock);
1212
1213        if ((me_filep != NULL) && (me_filep != filep)) {
1214                spin_unlock(&me_lock);
1215                PERROR("Driver System is logged by another process.\n");
1216
1217                for (i = 0; i < karg.count; i++) {
1218                        list[i].iErrno = ME_ERRNO_LOCKED;
1219                }
1220        } else {
1221                me_count++;
1222                spin_unlock(&me_lock);
1223
1224                for (i = 0; i < karg.count; i++) {
1225                        down_read(&me_rwsem);
1226                        k = 0;
1227                        list_for_each(pos, &me_device_list) {
1228                                if (k == list[i].iDevice) {
1229                                        device =
1230                                            list_entry(pos, me_device_t, list);
1231                                        break;
1232                                }
1233
1234                                k++;
1235                        }
1236
1237                        if (pos == &me_device_list) {
1238                                up_read(&me_rwsem);
1239                                PERROR("Invalid device number specified.\n");
1240                                list[i].iErrno = ME_ERRNO_INVALID_DEVICE;
1241                                karg.errno = ME_ERRNO_INVALID_DEVICE;
1242                                break;
1243                        } else {
1244                                list[i].iErrno =
1245                                    device->me_device_io_stream_start(device,
1246                                                                      filep,
1247                                                                      list[i].
1248                                                                      iSubdevice,
1249                                                                      list[i].
1250                                                                      iStartMode,
1251                                                                      list[i].
1252                                                                      iTimeOut,
1253                                                                      list[i].
1254                                                                      iFlags);
1255
1256                                if (list[i].iErrno) {
1257                                        up_read(&me_rwsem);
1258                                        karg.errno = list[i].iErrno;
1259                                        break;
1260                                }
1261                        }
1262
1263                        up_read(&me_rwsem);
1264                }
1265
1266                spin_lock(&me_lock);
1267
1268                me_count--;
1269                spin_unlock(&me_lock);
1270        }
1271
1272        err = copy_to_user(arg, &karg, sizeof(me_io_stream_start_t));
1273
1274        if (err) {
1275                PERROR("Can't copy arguments to user space.\n");
1276                kfree(list);
1277                return -EFAULT;
1278        }
1279
1280        err =
1281            copy_to_user(karg.start_list, list,
1282                         sizeof(meIOStreamStart_t) * karg.count);
1283
1284        if (err) {
1285                PERROR("Can't copy start list to user space.\n");
1286                kfree(list);
1287                return -EFAULT;
1288        }
1289
1290        kfree(list);
1291
1292        return err;
1293}
1294
1295static int me_io_single(struct file *filep, me_io_single_t * arg)
1296{
1297        int err;
1298        int i, k;
1299
1300        struct list_head *pos;
1301        me_device_t *device;
1302        me_io_single_t karg;
1303        meIOSingle_t *list;
1304
1305        PDEBUG("executed.\n");
1306
1307        err = copy_from_user(&karg, arg, sizeof(me_io_single_t));
1308
1309        if (err) {
1310                PERROR("Can't copy arguments to kernel space.\n");
1311                return -EFAULT;
1312        }
1313
1314        karg.errno = ME_ERRNO_SUCCESS;
1315
1316        list = kmalloc(sizeof(meIOSingle_t) * karg.count, GFP_KERNEL);
1317
1318        if (!list) {
1319                PERROR("Can't get buffer for single list.\n");
1320                return -ENOMEM;
1321        }
1322
1323        err =
1324            copy_from_user(list, karg.single_list,
1325                           sizeof(meIOSingle_t) * karg.count);
1326
1327        if (err) {
1328                PERROR("Can't copy single list to kernel space.\n");
1329                kfree(list);
1330                return -EFAULT;
1331        }
1332
1333        spin_lock(&me_lock);
1334
1335        if ((me_filep != NULL) && (me_filep != filep)) {
1336                spin_unlock(&me_lock);
1337                PERROR("Driver System is logged by another process.\n");
1338
1339                for (i = 0; i < karg.count; i++) {
1340                        list[i].iErrno = ME_ERRNO_LOCKED;
1341                }
1342        } else {
1343                me_count++;
1344                spin_unlock(&me_lock);
1345
1346                for (i = 0; i < karg.count; i++) {
1347                        k = 0;
1348
1349                        down_read(&me_rwsem);
1350
1351                        list_for_each(pos, &me_device_list) {
1352                                if (k == list[i].iDevice) {
1353                                        device =
1354                                            list_entry(pos, me_device_t, list);
1355                                        break;
1356                                }
1357
1358                                k++;
1359                        }
1360
1361                        if (pos == &me_device_list) {
1362                                up_read(&me_rwsem);
1363                                PERROR("Invalid device number specified.\n");
1364                                list[i].iErrno = ME_ERRNO_INVALID_DEVICE;
1365                                karg.errno = ME_ERRNO_INVALID_DEVICE;
1366                                break;
1367                        } else {
1368                                if (list[i].iDir == ME_DIR_OUTPUT) {
1369                                        list[i].iErrno =
1370                                            device->
1371                                            me_device_io_single_write(device,
1372                                                                      filep,
1373                                                                      list[i].
1374                                                                      iSubdevice,
1375                                                                      list[i].
1376                                                                      iChannel,
1377                                                                      list[i].
1378                                                                      iValue,
1379                                                                      list[i].
1380                                                                      iTimeOut,
1381                                                                      list[i].
1382                                                                      iFlags);
1383
1384                                        if (list[i].iErrno) {
1385                                                up_read(&me_rwsem);
1386                                                karg.errno = list[i].iErrno;
1387                                                break;
1388                                        }
1389                                } else if (list[i].iDir == ME_DIR_INPUT) {
1390                                        list[i].iErrno =
1391                                            device->
1392                                            me_device_io_single_read(device,
1393                                                                     filep,
1394                                                                     list[i].
1395                                                                     iSubdevice,
1396                                                                     list[i].
1397                                                                     iChannel,
1398                                                                     &list[i].
1399                                                                     iValue,
1400                                                                     list[i].
1401                                                                     iTimeOut,
1402                                                                     list[i].
1403                                                                     iFlags);
1404
1405                                        if (list[i].iErrno) {
1406                                                up_read(&me_rwsem);
1407                                                karg.errno = list[i].iErrno;
1408                                                break;
1409                                        }
1410                                } else {
1411                                        up_read(&me_rwsem);
1412                                        PERROR
1413                                            ("Invalid single direction specified.\n");
1414                                        list[i].iErrno = ME_ERRNO_INVALID_DIR;
1415                                        karg.errno = ME_ERRNO_INVALID_DIR;
1416                                        break;
1417                                }
1418                        }
1419
1420                        up_read(&me_rwsem);
1421                }
1422
1423                spin_lock(&me_lock);
1424
1425                me_count--;
1426                spin_unlock(&me_lock);
1427        }
1428
1429        err = copy_to_user(arg, &karg, sizeof(me_io_single_t));
1430
1431        if (err) {
1432                PERROR("Can't copy arguments to user space.\n");
1433                return -EFAULT;
1434        }
1435
1436        err =
1437            copy_to_user(karg.single_list, list,
1438                         sizeof(meIOSingle_t) * karg.count);
1439
1440        if (err) {
1441                PERROR("Can't copy single list to user space.\n");
1442                kfree(list);
1443                return -EFAULT;
1444        }
1445
1446        kfree(list);
1447
1448        return err;
1449}
1450
1451static int me_io_stream_config(struct file *filep, me_io_stream_config_t * arg)
1452{
1453        int err;
1454        int k = 0;
1455
1456        struct list_head *pos;
1457        me_device_t *device;
1458        me_io_stream_config_t karg;
1459        meIOStreamConfig_t *list;
1460
1461        PDEBUG("executed.\n");
1462
1463        err = copy_from_user(&karg, arg, sizeof(me_io_stream_config_t));
1464
1465        if (err) {
1466                PERROR("Can't copy arguments to kernel space.\n");
1467                return -EFAULT;
1468        }
1469
1470        list = kmalloc(sizeof(meIOStreamConfig_t) * karg.count, GFP_KERNEL);
1471
1472        if (!list) {
1473                PERROR("Can't get buffer for config list.\n");
1474                return -ENOMEM;
1475        }
1476
1477        err =
1478            copy_from_user(list, karg.config_list,
1479                           sizeof(meIOStreamConfig_t) * karg.count);
1480
1481        if (err) {
1482                PERROR("Can't copy config list to kernel space.\n");
1483                kfree(list);
1484                return -EFAULT;
1485        }
1486
1487        spin_lock(&me_lock);
1488
1489        if ((me_filep != NULL) && (me_filep != filep)) {
1490                spin_unlock(&me_lock);
1491                PERROR("Driver System is logged by another process.\n");
1492                karg.errno = ME_ERRNO_LOCKED;
1493        } else {
1494                me_count++;
1495                spin_unlock(&me_lock);
1496
1497                down_read(&me_rwsem);
1498
1499                list_for_each(pos, &me_device_list) {
1500                        if (k == karg.device) {
1501                                device = list_entry(pos, me_device_t, list);
1502                                break;
1503                        }
1504
1505                        k++;
1506                }
1507
1508                if (pos == &me_device_list) {
1509                        PERROR("Invalid device number specified.\n");
1510                        karg.errno = ME_ERRNO_INVALID_DEVICE;
1511                } else {
1512                        karg.errno =
1513                            device->me_device_io_stream_config(device, filep,
1514                                                               karg.subdevice,
1515                                                               list, karg.count,
1516                                                               &karg.trigger,
1517                                                               karg.
1518                                                               fifo_irq_threshold,
1519                                                               karg.flags);
1520                }
1521
1522                up_read(&me_rwsem);
1523
1524                spin_lock(&me_lock);
1525                me_count--;
1526                spin_unlock(&me_lock);
1527        }
1528
1529        err = copy_to_user(arg, &karg, sizeof(me_io_stream_config_t));
1530
1531        if (err) {
1532                PERROR("Can't copy back to user space.\n");
1533                kfree(list);
1534                return -EFAULT;
1535        }
1536
1537        kfree(list);
1538
1539        return err;
1540}
1541
1542static int me_query_number_devices(struct file *filep,
1543                                   me_query_number_devices_t * arg)
1544{
1545        int err;
1546        me_query_number_devices_t karg;
1547
1548        struct list_head *pos;
1549
1550        PDEBUG("executed.\n");
1551
1552        karg.number = 0;
1553        down_read(&me_rwsem);
1554        list_for_each(pos, &me_device_list) {
1555                karg.number++;
1556        }
1557
1558        up_read(&me_rwsem);
1559
1560        karg.errno = ME_ERRNO_SUCCESS;
1561
1562        err = copy_to_user(arg, &karg, sizeof(me_query_number_devices_t));
1563
1564        if (err) {
1565                PERROR("Can't copy query back to user space.\n");
1566                return -EFAULT;
1567        }
1568
1569        return 0;
1570}
1571
1572static int me_io_stream_stop(struct file *filep, me_io_stream_stop_t * arg)
1573{
1574        int err;
1575        int i, k;
1576
1577        struct list_head *pos;
1578        me_device_t *device;
1579        me_io_stream_stop_t karg;
1580        meIOStreamStop_t *list;
1581
1582        PDEBUG("executed.\n");
1583
1584        err = copy_from_user(&karg, arg, sizeof(me_io_stream_stop_t));
1585
1586        if (err) {
1587                PERROR("Can't copy arguments to kernel space.\n");
1588                return -EFAULT;
1589        }
1590
1591        karg.errno = ME_ERRNO_SUCCESS;
1592
1593        list = kmalloc(sizeof(meIOStreamStop_t) * karg.count, GFP_KERNEL);
1594
1595        if (!list) {
1596                PERROR("Can't get buffer for stop list.\n");
1597                return -ENOMEM;
1598        }
1599
1600        err =
1601            copy_from_user(list, karg.stop_list,
1602                           sizeof(meIOStreamStop_t) * karg.count);
1603
1604        if (err) {
1605                PERROR("Can't copy stop list to kernel space.\n");
1606                kfree(list);
1607                return -EFAULT;
1608        }
1609
1610        spin_lock(&me_lock);
1611
1612        if ((me_filep != NULL) && (me_filep != filep)) {
1613                spin_unlock(&me_lock);
1614                PERROR("Driver System is logged by another process.\n");
1615
1616                for (i = 0; i < karg.count; i++) {
1617                        list[i].iErrno = ME_ERRNO_LOCKED;
1618                }
1619        } else {
1620                me_count++;
1621                spin_unlock(&me_lock);
1622
1623                for (i = 0; i < karg.count; i++) {
1624                        k = 0;
1625                        down_read(&me_rwsem);
1626                        list_for_each(pos, &me_device_list) {
1627                                if (k == list[i].iDevice) {
1628                                        device =
1629                                            list_entry(pos, me_device_t, list);
1630                                        break;
1631                                }
1632
1633                                k++;
1634                        }
1635
1636                        if (pos == &me_device_list) {
1637                                up_read(&me_rwsem);
1638                                PERROR("Invalid device number specified.\n");
1639                                list[i].iErrno = ME_ERRNO_INVALID_DEVICE;
1640                                karg.errno = ME_ERRNO_INVALID_DEVICE;
1641                                break;
1642                        } else {
1643                                list[i].iErrno =
1644                                    device->me_device_io_stream_stop(device,
1645                                                                     filep,
1646                                                                     list[i].
1647                                                                     iSubdevice,
1648                                                                     list[i].
1649                                                                     iStopMode,
1650                                                                     list[i].
1651                                                                     iFlags);
1652
1653                                if (list[i].iErrno) {
1654                                        up_read(&me_rwsem);
1655                                        karg.errno = list[i].iErrno;
1656                                        break;
1657                                }
1658                        }
1659
1660                        up_read(&me_rwsem);
1661                }
1662
1663                spin_lock(&me_lock);
1664
1665                me_count--;
1666                spin_unlock(&me_lock);
1667        }
1668
1669        err = copy_to_user(arg, &karg, sizeof(me_io_stream_stop_t));
1670
1671        if (err) {
1672                PERROR("Can't copy arguments to user space.\n");
1673                return -EFAULT;
1674        }
1675
1676        err =
1677            copy_to_user(karg.stop_list, list,
1678                         sizeof(meIOStreamStop_t) * karg.count);
1679
1680        if (err) {
1681                PERROR("Can't copy stop list to user space.\n");
1682                kfree(list);
1683                return -EFAULT;
1684        }
1685
1686        kfree(list);
1687
1688        return err;
1689}
1690
1691/*  //me_probe_usb
1692static int me_probe_usb(struct usb_interface *interface, const struct usb_device_id *id)
1693{
1694        //int err;
1695        //me_usb_constructor_t *constructor = NULL;
1696        me_device_t *n_device = NULL;
1697
1698        PDEBUG("executed.\n");
1699
1700        switch (id->idProduct)
1701        {
1702                        case USB_DEVICE_ID_MEPHISTO_S1:
1703                                if((constructor = symbol_get(mephisto_s1_constructor)) == NULL){
1704                                        err = request_module(MEPHISTO_S1_NAME);
1705                                        if(err){
1706                                                PERROR("Error while request for module %s.\n", MEPHISTO_S1_NAME);
1707                                                return -ENODEV;
1708                                        }
1709                                        if((constructor = symbol_get(mephisto_s1_constructor)) == NULL){
1710                                                PERROR("Can't get %s driver module constructor.\n", MEPHISTO_S1_NAME);
1711                                                return -ENODEV;
1712                                        }
1713                                }
1714
1715                                if((n_device = (*constructor)(interface)) == NULL){
1716                                        symbol_put(mephisto_s1_constructor);
1717                                        PERROR("Can't get device instance of %s driver module.\n", MEPHISTO_S1_NAME);
1718                                        return -ENODEV;
1719                                }
1720
1721                                break;
1722
1723                default:
1724                        PERROR("Invalid product id.\n");
1725
1726                        return -EINVAL;
1727        }
1728
1729        return insert_to_device_list(n_device);
1730}
1731*/
1732
1733/*  //me_disconnect_usb
1734static void me_disconnect_usb(struct usb_interface *interface)
1735{
1736
1737        struct usb_device *device = interface_to_usbdev(interface);
1738        int vendor_id = device->descriptor.idVendor;
1739        int device_id = device->descriptor.idProduct;
1740        int serial_no;
1741
1742        sscanf(&device->serial[2], "%x", &serial_no);
1743
1744        PDEBUG("executed.\n");
1745
1746        PINFO("Vendor id = 0x%08X\n", vendor_id);
1747        PINFO("Device id = 0x%08X\n", device_id);
1748        PINFO("Serial Number = 0x%08X\n", serial_no);
1749
1750        replace_with_dummy(vendor_id, device_id, serial_no);
1751}
1752*/
1753
1754static int me_ioctl(struct inode *inodep,
1755                    struct file *filep, unsigned int service, unsigned long arg)
1756{
1757
1758        PDEBUG("executed.\n");
1759
1760        if (_IOC_TYPE(service) != MEMAIN_MAGIC) {
1761                PERROR("Invalid magic number.\n");
1762                return -ENOTTY;
1763        }
1764
1765        PDEBUG("service number: 0x%x.\n", service);
1766
1767        switch (service) {
1768        case ME_IO_IRQ_ENABLE:
1769                return me_io_irq_start(filep, (me_io_irq_start_t *) arg);
1770
1771        case ME_IO_IRQ_WAIT:
1772                return me_io_irq_wait(filep, (me_io_irq_wait_t *) arg);
1773
1774        case ME_IO_IRQ_DISABLE:
1775                return me_io_irq_stop(filep, (me_io_irq_stop_t *) arg);
1776
1777        case ME_IO_RESET_DEVICE:
1778                return me_io_reset_device(filep, (me_io_reset_device_t *) arg);
1779
1780        case ME_IO_RESET_SUBDEVICE:
1781                return me_io_reset_subdevice(filep,
1782                                             (me_io_reset_subdevice_t *) arg);
1783
1784        case ME_IO_SINGLE_CONFIG:
1785                return me_io_single_config(filep,
1786                                           (me_io_single_config_t *) arg);
1787
1788        case ME_IO_SINGLE:
1789                return me_io_single(filep, (me_io_single_t *) arg);
1790
1791        case ME_IO_STREAM_CONFIG:
1792                return me_io_stream_config(filep,
1793                                           (me_io_stream_config_t *) arg);
1794
1795        case ME_IO_STREAM_NEW_VALUES:
1796                return me_io_stream_new_values(filep,
1797                                               (me_io_stream_new_values_t *)
1798                                               arg);
1799
1800        case ME_IO_STREAM_READ:
1801                return me_io_stream_read(filep, (me_io_stream_read_t *) arg);
1802
1803        case ME_IO_STREAM_START:
1804                return me_io_stream_start(filep, (me_io_stream_start_t *) arg);
1805
1806        case ME_IO_STREAM_STATUS:
1807                return me_io_stream_status(filep,
1808                                           (me_io_stream_status_t *) arg);
1809
1810        case ME_IO_STREAM_STOP:
1811                return me_io_stream_stop(filep, (me_io_stream_stop_t *) arg);
1812
1813        case ME_IO_STREAM_WRITE:
1814                return me_io_stream_write(filep, (me_io_stream_write_t *) arg);
1815
1816        case ME_LOCK_DRIVER:
1817                return me_lock_driver(filep, (me_lock_driver_t *) arg);
1818
1819        case ME_LOCK_DEVICE:
1820                return me_lock_device(filep, (me_lock_device_t *) arg);
1821
1822        case ME_LOCK_SUBDEVICE:
1823                return me_lock_subdevice(filep, (me_lock_subdevice_t *) arg);
1824
1825        case ME_QUERY_INFO_DEVICE:
1826                return me_query_info_device(filep,
1827                                            (me_query_info_device_t *) arg);
1828
1829        case ME_QUERY_DESCRIPTION_DEVICE:
1830                return me_query_description_device(filep,
1831                                                   (me_query_description_device_t
1832                                                    *) arg);
1833
1834        case ME_QUERY_NAME_DEVICE:
1835                return me_query_name_device(filep,
1836                                            (me_query_name_device_t *) arg);
1837
1838        case ME_QUERY_NAME_DEVICE_DRIVER:
1839                return me_query_name_device_driver(filep,
1840                                                   (me_query_name_device_driver_t
1841                                                    *) arg);
1842
1843        case ME_QUERY_NUMBER_DEVICES:
1844                return me_query_number_devices(filep,
1845                                               (me_query_number_devices_t *)
1846                                               arg);
1847
1848        case ME_QUERY_NUMBER_SUBDEVICES:
1849                return me_query_number_subdevices(filep,
1850                                                  (me_query_number_subdevices_t
1851                                                   *) arg);
1852
1853        case ME_QUERY_NUMBER_CHANNELS:
1854                return me_query_number_channels(filep,
1855                                                (me_query_number_channels_t *)
1856                                                arg);
1857
1858        case ME_QUERY_NUMBER_RANGES:
1859                return me_query_number_ranges(filep,
1860                                              (me_query_number_ranges_t *) arg);
1861
1862        case ME_QUERY_RANGE_BY_MIN_MAX:
1863                return me_query_range_by_min_max(filep,
1864                                                 (me_query_range_by_min_max_t *)
1865                                                 arg);
1866
1867        case ME_QUERY_RANGE_INFO:
1868                return me_query_range_info(filep,
1869                                           (me_query_range_info_t *) arg);
1870
1871        case ME_QUERY_SUBDEVICE_BY_TYPE:
1872                return me_query_subdevice_by_type(filep,
1873                                                  (me_query_subdevice_by_type_t
1874                                                   *) arg);
1875
1876        case ME_QUERY_SUBDEVICE_TYPE:
1877                return me_query_subdevice_type(filep,
1878                                               (me_query_subdevice_type_t *)
1879                                               arg);
1880
1881        case ME_QUERY_SUBDEVICE_CAPS:
1882                return me_query_subdevice_caps(filep,
1883                                               (me_query_subdevice_caps_t *)
1884                                               arg);
1885
1886        case ME_QUERY_SUBDEVICE_CAPS_ARGS:
1887                return me_query_subdevice_caps_args(filep,
1888                                                    (me_query_subdevice_caps_args_t
1889                                                     *) arg);
1890
1891        case ME_QUERY_TIMER:
1892                return me_query_timer(filep, (me_query_timer_t *) arg);
1893
1894        case ME_QUERY_VERSION_MAIN_DRIVER:
1895                return me_query_version_main_driver(filep,
1896                                                    (me_query_version_main_driver_t
1897                                                     *) arg);
1898
1899        case ME_QUERY_VERSION_DEVICE_DRIVER:
1900                return me_query_version_device_driver(filep,
1901                                                      (me_query_version_device_driver_t
1902                                                       *) arg);
1903
1904        case ME_CONFIG_LOAD:
1905                return me_config_load(filep, (me_config_load_t *) arg);
1906        }
1907
1908        PERROR("Invalid ioctl number.\n");
1909        return -ENOTTY;
1910}
1911
1912// Init and exit of module.
1913static int memain_init(void)
1914{
1915        int result = 0;
1916        dev_t dev = MKDEV(major, 0);
1917
1918        PDEBUG("executed.\n");
1919
1920        // Register pci driver. This will return 0 if the PCI subsystem is not available.
1921        result = pci_register_driver(&me_pci_driver);
1922
1923        if (result < 0) {
1924                PERROR("Can't register pci driver.\n");
1925                goto INIT_ERROR_1;
1926        }
1927
1928/*
1929        // Register usb driver. This will return -ENODEV if no USB subsystem is available.
1930        result = usb_register(&me_usb_driver);
1931
1932        if (result)
1933        {
1934                if (result == -ENODEV)
1935                {
1936                        PERROR("No USB subsystem available.\n");
1937                }
1938                else
1939                {
1940                        PERROR("Can't register usb driver.\n");
1941                        goto INIT_ERROR_2;
1942                }
1943        }
1944*/
1945        // Register the character device.
1946        if (major) {
1947                result = register_chrdev_region(dev, 1, MEMAIN_NAME);
1948        } else {
1949                result = alloc_chrdev_region(&dev, 0, 1, MEMAIN_NAME);
1950                major = MAJOR(dev);
1951        }
1952
1953        if (result < 0) {
1954                PERROR("Can't get major driver no.\n");
1955                goto INIT_ERROR_3;
1956        }
1957
1958        cdevp = cdev_alloc();
1959
1960        if (!cdevp) {
1961                PERROR("Can't get character device structure.\n");
1962                result = -ENOMEM;
1963                goto INIT_ERROR_4;
1964        }
1965
1966        cdevp->ops = &me_file_operations;
1967
1968        cdevp->owner = THIS_MODULE;
1969
1970        result = cdev_add(cdevp, dev, 1);
1971
1972        if (result < 0) {
1973                PERROR("Cannot add character device structure.\n");
1974                goto INIT_ERROR_5;
1975        }
1976
1977        return 0;
1978
1979      INIT_ERROR_5:
1980        cdev_del(cdevp);
1981
1982      INIT_ERROR_4:
1983        unregister_chrdev_region(dev, 1);
1984
1985      INIT_ERROR_3:
1986//      usb_deregister(&me_usb_driver);
1987
1988//INIT_ERROR_2:
1989        pci_unregister_driver(&me_pci_driver);
1990        clear_device_list();
1991
1992      INIT_ERROR_1:
1993        return result;
1994}
1995
1996static void __exit memain_exit(void)
1997{
1998        dev_t dev = MKDEV(major, 0);
1999
2000        PDEBUG("executed.\n");
2001
2002        cdev_del(cdevp);
2003        unregister_chrdev_region(dev, 1);
2004        pci_unregister_driver(&me_pci_driver);
2005//      usb_deregister(&me_usb_driver);
2006        clear_device_list();
2007}
2008
2009module_init(memain_init);
2010module_exit(memain_exit);
2011
2012// Administrative stuff for modinfo.
2013MODULE_AUTHOR
2014    ("Guenter Gebhardt <g.gebhardt@meilhaus.de> & Krzysztof Gantzke <k.gantzke@meilhaus.de>");
2015MODULE_DESCRIPTION("Central module for Meilhaus Driver System.");
2016MODULE_SUPPORTED_DEVICE("Meilhaus PCI/cPCI boards.");
2017MODULE_LICENSE("GPL");
2018
2019#ifdef BOSCH
2020// Export the flag for the BOSCH firmware.
2021EXPORT_SYMBOL(me_bosch_fw);
2022#endif // BOSCH
2023
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.