diff options
Diffstat (limited to 'drivers/staging/meilhaus/memain.c')
-rw-r--r-- | drivers/staging/meilhaus/memain.c | 2084 |
1 files changed, 0 insertions, 2084 deletions
diff --git a/drivers/staging/meilhaus/memain.c b/drivers/staging/meilhaus/memain.c deleted file mode 100644 index c4908549192..00000000000 --- a/drivers/staging/meilhaus/memain.c +++ /dev/null @@ -1,2084 +0,0 @@ -/** - * @file memain.c - * - * @brief Main Meilhaus device driver. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - * @author Krzysztof Gantzke (k.gantzke@meilhaus.de) - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -#ifndef MODULE -# define MODULE -#endif - -#include <linux/module.h> -#include <linux/pci.h> -//#include <linux/usb.h> -#include <linux/errno.h> -#include <linux/uaccess.h> -#include <linux/miscdevice.h> -#include <linux/rwsem.h> - -#include "medefines.h" -#include "metypes.h" -#include "meerror.h" - -#include "medebug.h" -#include "memain.h" -#include "medevice.h" -#include "meioctl.h" -#include "mecommon.h" - -/* Module parameters -*/ - -#ifdef BOSCH -static unsigned int me_bosch_fw = 0; -EXPORT_SYMBOL(me_bosch_fw); - -# ifdef module_param -module_param(me_bosch_fw, int, S_IRUGO); -# else -MODULE_PARM(me_bosch_fw, "i"); -# endif - -MODULE_PARM_DESC(me_bosch_fw, - "Flags which signals the ME-4600 driver to load the bosch firmware (default = 0)."); -#endif //BOSCH - -/* Global Driver Lock -*/ - -static struct file *me_filep = NULL; -static int me_count = 0; -static DEFINE_SPINLOCK(me_lock); -static DECLARE_RWSEM(me_rwsem); - -/* Board instances are kept in a global list */ -LIST_HEAD(me_device_list); - -/* Prototypes -*/ - -static int me_probe_pci(struct pci_dev *dev, const struct pci_device_id *id); -static void me_remove_pci(struct pci_dev *dev); -static int insert_to_device_list(me_device_t *n_device); -static int replace_with_dummy(int vendor_id, int device_id, int serial_no); -static void clear_device_list(void); -static int me_open(struct inode *inode_ptr, struct file *filep); -static int me_release(struct inode *, struct file *); -static int me_ioctl(struct inode *, struct file *, unsigned int, unsigned long); -//static int me_probe_usb(struct usb_interface *interface, const struct usb_device_id *id); -//static void me_disconnect_usb(struct usb_interface *interface); - -/* File operations provided by the module -*/ - -static const struct file_operations me_file_operations = { - .owner = THIS_MODULE, - .ioctl = me_ioctl, - .open = me_open, - .release = me_release, -}; - -static const struct pci_device_id me_pci_table[] = { - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME1000) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME1000_A) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME1000_B) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME1400) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME140A) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME140B) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME14E0) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME14EA) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME14EB) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME140C) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME140D) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME1600_4U) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME1600_8U) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME1600_12U) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME1600_16U) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME1600_16U_8I) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4610) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4650) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4660) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4660I) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4670) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4670I) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4670S) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4670IS) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4680) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4680I) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4680S) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4680IS) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6004) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6008) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME600F) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6014) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6018) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME601F) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6034) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6038) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME603F) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6104) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6108) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME610F) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6114) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6118) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME611F) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6134) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6138) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME613F) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6044) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6048) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME604F) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6054) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6058) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME605F) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6074) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6078) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME607F) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6144) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6148) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME614F) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6154) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6158) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME615F) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6174) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6178) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME617F) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6259) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6359) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME0630) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME8100_A) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME8100_B) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME8200_A) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME8200_B) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME0940) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME0950) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME0960) }, - - { } -}; -MODULE_DEVICE_TABLE(pci, me_pci_table); - -static struct pci_driver me_pci_driver = { - .name = MEMAIN_NAME, - .id_table = me_pci_table, - .probe = me_probe_pci, - .remove = __devexit_p(me_remove_pci), -}; - -/* -static struct usb_device_id me_usb_table[] = { - { USB_DEVICE(USB_VENDOR_ID_MEPHISTO_S1, USB_DEVICE_ID_MEPHISTO_S1) }, - { 0 } -}; -MODULE_DEVICE_TABLE (usb, me_usb_table); - -static struct usb_driver me_usb_driver = -{ - .name = MEMAIN_NAME, - .id_table = me_usb_table, - .probe = me_probe_usb, - .disconnect = me_disconnect_usb -}; -*/ - -#ifdef ME_LOCK_MULTIPLEX_TEMPLATE -ME_LOCK_MULTIPLEX_TEMPLATE("me_lock_device", - me_lock_device_t, - me_lock_device, - me_device_lock_device, - (device, filep, karg.lock, karg.flags)) - - ME_LOCK_MULTIPLEX_TEMPLATE("me_lock_subdevice", - me_lock_subdevice_t, - me_lock_subdevice, - me_device_lock_subdevice, - (device, filep, karg.subdevice, karg.lock, - karg.flags)) -#else -#error macro ME_LOCK_MULTIPLEX_TEMPLATE not defined -#endif - -#ifdef ME_IO_MULTIPLEX_TEMPLATE -ME_IO_MULTIPLEX_TEMPLATE("me_io_irq_start", - me_io_irq_start_t, - me_io_irq_start, - me_device_io_irq_start, - (device, - filep, - karg.subdevice, - karg.channel, - karg.irq_source, - karg.irq_edge, karg.irq_arg, karg.flags)) - - ME_IO_MULTIPLEX_TEMPLATE("me_io_irq_wait", - me_io_irq_wait_t, - me_io_irq_wait, - me_device_io_irq_wait, - (device, - filep, - karg.subdevice, - karg.channel, - &karg.irq_count, &karg.value, karg.time_out, karg.flags)) - - ME_IO_MULTIPLEX_TEMPLATE("me_io_irq_stop", - me_io_irq_stop_t, - me_io_irq_stop, - me_device_io_irq_stop, - (device, - filep, karg.subdevice, karg.channel, karg.flags)) - - ME_IO_MULTIPLEX_TEMPLATE("me_io_reset_device", - me_io_reset_device_t, - me_io_reset_device, - me_device_io_reset_device, (device, filep, karg.flags)) - - ME_IO_MULTIPLEX_TEMPLATE("me_io_reset_subdevice", - me_io_reset_subdevice_t, - me_io_reset_subdevice, - me_device_io_reset_subdevice, - (device, filep, karg.subdevice, karg.flags)) - - ME_IO_MULTIPLEX_TEMPLATE("me_io_single_config", - me_io_single_config_t, - me_io_single_config, - me_device_io_single_config, - (device, - filep, - karg.subdevice, - karg.channel, - karg.single_config, - karg.ref, - karg.trig_chan, - karg.trig_type, karg.trig_edge, karg.flags)) - - ME_IO_MULTIPLEX_TEMPLATE("me_io_stream_new_values", - me_io_stream_new_values_t, - me_io_stream_new_values, - me_device_io_stream_new_values, - (device, - filep, - karg.subdevice, karg.time_out, &karg.count, karg.flags)) - - ME_IO_MULTIPLEX_TEMPLATE("me_io_stream_read", - me_io_stream_read_t, - me_io_stream_read, - me_device_io_stream_read, - (device, - filep, - karg.subdevice, - karg.read_mode, karg.values, &karg.count, karg.flags)) - - ME_IO_MULTIPLEX_TEMPLATE("me_io_stream_status", - me_io_stream_status_t, - me_io_stream_status, - me_device_io_stream_status, - (device, - filep, - karg.subdevice, - karg.wait, &karg.status, &karg.count, karg.flags)) - - ME_IO_MULTIPLEX_TEMPLATE("me_io_stream_write", - me_io_stream_write_t, - me_io_stream_write, - me_device_io_stream_write, - (device, - filep, - karg.subdevice, - karg.write_mode, karg.values, &karg.count, karg.flags)) -#else -#error macro ME_IO_MULTIPLEX_TEMPLATE not defined -#endif - -#ifdef ME_QUERY_MULTIPLEX_STR_TEMPLATE -ME_QUERY_MULTIPLEX_STR_TEMPLATE("me_query_name_device", - me_query_name_device_t, - me_query_name_device, - me_device_query_name_device, (device, &msg)) - - ME_QUERY_MULTIPLEX_STR_TEMPLATE("me_query_name_device_driver", - me_query_name_device_driver_t, - me_query_name_device_driver, - me_device_query_name_device_driver, - (device, &msg)) - - ME_QUERY_MULTIPLEX_STR_TEMPLATE("me_query_description_device", - me_query_description_device_t, - me_query_description_device, - me_device_query_description_device, - (device, &msg)) -#else -#error macro ME_QUERY_MULTIPLEX_STR_TEMPLATE not defined -#endif - -#ifdef ME_QUERY_MULTIPLEX_TEMPLATE -ME_QUERY_MULTIPLEX_TEMPLATE("me_query_info_device", - me_query_info_device_t, - me_query_info_device, - me_device_query_info_device, - (device, - &karg.vendor_id, - &karg.device_id, - &karg.serial_no, - &karg.bus_type, - &karg.bus_no, - &karg.dev_no, &karg.func_no, &karg.plugged)) - - ME_QUERY_MULTIPLEX_TEMPLATE("me_query_number_subdevices", - me_query_number_subdevices_t, - me_query_number_subdevices, - me_device_query_number_subdevices, - (device, &karg.number)) - - ME_QUERY_MULTIPLEX_TEMPLATE("me_query_number_channels", - me_query_number_channels_t, - me_query_number_channels, - me_device_query_number_channels, - (device, karg.subdevice, &karg.number)) - - ME_QUERY_MULTIPLEX_TEMPLATE("me_query_subdevice_by_type", - me_query_subdevice_by_type_t, - me_query_subdevice_by_type, - me_device_query_subdevice_by_type, - (device, - karg.start_subdevice, - karg.type, karg.subtype, &karg.subdevice)) - - ME_QUERY_MULTIPLEX_TEMPLATE("me_query_subdevice_type", - me_query_subdevice_type_t, - me_query_subdevice_type, - me_device_query_subdevice_type, - (device, karg.subdevice, &karg.type, &karg.subtype)) - - ME_QUERY_MULTIPLEX_TEMPLATE("me_query_subdevice_caps", - me_query_subdevice_caps_t, - me_query_subdevice_caps, - me_device_query_subdevice_caps, - (device, karg.subdevice, &karg.caps)) - - ME_QUERY_MULTIPLEX_TEMPLATE("me_query_subdevice_caps_args", - me_query_subdevice_caps_args_t, - me_query_subdevice_caps_args, - me_device_query_subdevice_caps_args, - (device, karg.subdevice, karg.cap, karg.args, - karg.count)) - - ME_QUERY_MULTIPLEX_TEMPLATE("me_query_number_ranges", - me_query_number_ranges_t, - me_query_number_ranges, - me_device_query_number_ranges, - (device, karg.subdevice, karg.unit, &karg.number)) - - ME_QUERY_MULTIPLEX_TEMPLATE("me_query_range_by_min_max", - me_query_range_by_min_max_t, - me_query_range_by_min_max, - me_device_query_range_by_min_max, - (device, - karg.subdevice, - karg.unit, - &karg.min, &karg.max, &karg.max_data, &karg.range)) - - ME_QUERY_MULTIPLEX_TEMPLATE("me_query_range_info", - me_query_range_info_t, - me_query_range_info, - me_device_query_range_info, - (device, - karg.subdevice, - karg.range, - &karg.unit, &karg.min, &karg.max, &karg.max_data)) - - ME_QUERY_MULTIPLEX_TEMPLATE("me_query_timer", - me_query_timer_t, - me_query_timer, - me_device_query_timer, - (device, - karg.subdevice, - karg.timer, - &karg.base_frequency, - &karg.min_ticks, &karg.max_ticks)) - - ME_QUERY_MULTIPLEX_TEMPLATE("me_query_version_device_driver", - me_query_version_device_driver_t, - me_query_version_device_driver, - me_device_query_version_device_driver, - (device, &karg.version)) -#else -#error macro ME_QUERY_MULTIPLEX_TEMPLATE not defined -#endif - -/** ******************************************************************************** **/ - -static me_device_t *get_dummy_instance(unsigned short vendor_id, - unsigned short device_id, - unsigned int serial_no, - int bus_type, - int bus_no, int dev_no, int func_no) -{ - int err; - me_dummy_constructor_t constructor = NULL; - me_device_t *instance; - - PDEBUG("executed.\n"); - - if ((constructor = symbol_get(medummy_constructor)) == NULL) { - err = request_module(MEDUMMY_NAME); - - if (err) { - PERROR("Error while request for module %s.\n", - MEDUMMY_NAME); - return NULL; - } - - if ((constructor = symbol_get(medummy_constructor)) == NULL) { - PERROR("Can't get %s driver module constructor.\n", - MEDUMMY_NAME); - return NULL; - } - } - - if ((instance = (*constructor) (vendor_id, - device_id, - serial_no, - bus_type, - bus_no, dev_no, func_no)) == NULL) - symbol_put(medummy_constructor); - - return instance; -} - -static int __devinit me_probe_pci(struct pci_dev *dev, - const struct pci_device_id *id) -{ - int err; - me_pci_constructor_t constructor = NULL; -#ifdef BOSCH - me_bosch_constructor_t constructor_bosch = NULL; -#endif - me_device_t *n_device = NULL; - uint32_t device; - - char constructor_name[24] = "me0000_pci_constructor"; - char module_name[7] = "me0000"; - - PDEBUG("executed.\n"); - device = dev->device; - if ((device & 0xF000) == 0x6000) { // Exceptions: me61xx, me62xx, me63xx are handled by one driver. - device &= 0xF0FF; - } - - constructor_name[2] += (char)((device >> 12) & 0x000F); - constructor_name[3] += (char)((device >> 8) & 0x000F); - PDEBUG("constructor_name: %s\n", constructor_name); - module_name[2] += (char)((device >> 12) & 0x000F); - module_name[3] += (char)((device >> 8) & 0x000F); - PDEBUG("module_name: %s\n", module_name); - - if ((constructor = - (me_pci_constructor_t) symbol_get(constructor_name)) == NULL) { - if (request_module("%s", module_name)) { - PERROR("Error while request for module %s.\n", - module_name); - return -ENODEV; - } - - if ((constructor = - (me_pci_constructor_t) symbol_get(constructor_name)) == - NULL) { - PERROR("Can't get %s driver module constructor.\n", - module_name); - return -ENODEV; - } - } -#ifdef BOSCH - if ((device & 0xF000) == 0x4000) { // Bosch build has differnt constructor for me4600. - if ((n_device = - (*constructor_bosch) (dev, me_bosch_fw)) == NULL) { - symbol_put(constructor_name); - PERROR - ("Can't get device instance of %s driver module.\n", - module_name); - return -ENODEV; - } - } else { -#endif - if ((n_device = (*constructor) (dev)) == NULL) { - symbol_put(constructor_name); - PERROR - ("Can't get device instance of %s driver module.\n", - module_name); - return -ENODEV; - } -#ifdef BOSCH - } -#endif - - insert_to_device_list(n_device); - err = - n_device->me_device_io_reset_device(n_device, NULL, - ME_IO_RESET_DEVICE_NO_FLAGS); - if (err) { - PERROR("Error while reseting device.\n"); - } else { - PDEBUG("Reseting device was sucessful.\n"); - } - return ME_ERRNO_SUCCESS; -} - -static void release_instance(me_device_t *device) -{ - int vendor_id; - int device_id; - int serial_no; - int bus_type; - int bus_no; - int dev_no; - int func_no; - int plugged; - - uint32_t dev_id; - - char constructor_name[24] = "me0000_pci_constructor"; - - PDEBUG("executed.\n"); - - device->me_device_query_info_device(device, - &vendor_id, - &device_id, - &serial_no, - &bus_type, - &bus_no, - &dev_no, &func_no, &plugged); - - dev_id = device_id; - device->me_device_destructor(device); - - if (plugged != ME_PLUGGED_IN) { - PDEBUG("release: medummy_constructor\n"); - - symbol_put("medummy_constructor"); - } else { - if ((dev_id & 0xF000) == 0x6000) { // Exceptions: me61xx, me62xx, me63xx are handled by one driver. - dev_id &= 0xF0FF; - } - - constructor_name[2] += (char)((dev_id >> 12) & 0x000F); - constructor_name[3] += (char)((dev_id >> 8) & 0x000F); - PDEBUG("release: %s\n", constructor_name); - - symbol_put(constructor_name); - } -} - -static int insert_to_device_list(me_device_t *n_device) -{ - me_device_t *o_device = NULL; - - struct list_head *pos; - int n_vendor_id; - int n_device_id; - int n_serial_no; - int n_bus_type; - int n_bus_no; - int n_dev_no; - int n_func_no; - int n_plugged; - int o_vendor_id; - int o_device_id; - int o_serial_no; - int o_bus_type; - int o_bus_no; - int o_dev_no; - int o_func_no; - int o_plugged; - - PDEBUG("executed.\n"); - - n_device->me_device_query_info_device(n_device, - &n_vendor_id, - &n_device_id, - &n_serial_no, - &n_bus_type, - &n_bus_no, - &n_dev_no, - &n_func_no, &n_plugged); - - down_write(&me_rwsem); - - list_for_each(pos, &me_device_list) { - o_device = list_entry(pos, me_device_t, list); - o_device->me_device_query_info_device(o_device, - &o_vendor_id, - &o_device_id, - &o_serial_no, - &o_bus_type, - &o_bus_no, - &o_dev_no, - &o_func_no, &o_plugged); - - if (o_plugged == ME_PLUGGED_OUT) { - if (((o_vendor_id == n_vendor_id) && - (o_device_id == n_device_id) && - (o_serial_no == n_serial_no) && - (o_bus_type == n_bus_type)) || - ((o_vendor_id == n_vendor_id) && - (o_device_id == n_device_id) && - (o_bus_type == n_bus_type) && - (o_bus_no == n_bus_no) && - (o_dev_no == n_dev_no) && - (o_func_no == n_func_no))) { - n_device->list.prev = pos->prev; - n_device->list.next = pos->next; - pos->prev->next = &n_device->list; - pos->next->prev = &n_device->list; - release_instance(o_device); - break; - } - } - } - - if (pos == &me_device_list) { - list_add_tail(&n_device->list, &me_device_list); - } - - up_write(&me_rwsem); - - return 0; -} - -static void __devexit me_remove_pci(struct pci_dev *dev) -{ - int vendor_id = dev->vendor; - int device_id = dev->device; - int subsystem_vendor = dev->subsystem_vendor; - int subsystem_device = dev->subsystem_device; - int serial_no = (subsystem_device << 16) | subsystem_vendor; - - PDEBUG("executed.\n"); - - PINFO("Vendor id = 0x%08X\n", vendor_id); - PINFO("Device id = 0x%08X\n", device_id); - PINFO("Serial Number = 0x%08X\n", serial_no); - - replace_with_dummy(vendor_id, device_id, serial_no); -} - -static int replace_with_dummy(int vendor_id, int device_id, int serial_no) -{ - - struct list_head *pos; - me_device_t *n_device = NULL; - me_device_t *o_device = NULL; - int o_vendor_id; - int o_device_id; - int o_serial_no; - int o_bus_type; - int o_bus_no; - int o_dev_no; - int o_func_no; - int o_plugged; - - PDEBUG("executed.\n"); - - down_write(&me_rwsem); - - list_for_each(pos, &me_device_list) { - o_device = list_entry(pos, me_device_t, list); - o_device->me_device_query_info_device(o_device, - &o_vendor_id, - &o_device_id, - &o_serial_no, - &o_bus_type, - &o_bus_no, - &o_dev_no, - &o_func_no, &o_plugged); - - if (o_plugged == ME_PLUGGED_IN) { - if (((o_vendor_id == vendor_id) && - (o_device_id == device_id) && - (o_serial_no == serial_no))) { - n_device = get_dummy_instance(o_vendor_id, - o_device_id, - o_serial_no, - o_bus_type, - o_bus_no, - o_dev_no, - o_func_no); - - if (!n_device) { - up_write(&me_rwsem); - PERROR("Cannot get dummy instance.\n"); - return 1; - } - - n_device->list.prev = pos->prev; - - n_device->list.next = pos->next; - pos->prev->next = &n_device->list; - pos->next->prev = &n_device->list; - release_instance(o_device); - break; - } - } - } - - up_write(&me_rwsem); - - return 0; -} - -static void clear_device_list(void) -{ - - struct list_head *entry; - me_device_t *device; - - // Clear the device info list . - down_write(&me_rwsem); - - while (!list_empty(&me_device_list)) { - entry = me_device_list.next; - device = list_entry(entry, me_device_t, list); - list_del(entry); - release_instance(device); - } - - up_write(&me_rwsem); -} - -static int lock_driver(struct file *filep, int lock, int flags) -{ - int err = ME_ERRNO_SUCCESS; - me_device_t *device; - - PDEBUG("executed.\n"); - - down_read(&me_rwsem); - - spin_lock(&me_lock); - - switch (lock) { - - case ME_LOCK_SET: - if (me_count) { - PERROR - ("Driver System is currently used by another process.\n"); - err = ME_ERRNO_USED; - } else if ((me_filep != NULL) && (me_filep != filep)) { - PERROR - ("Driver System is already logged by another process.\n"); - err = ME_ERRNO_LOCKED; - } else { - list_for_each_entry(device, &me_device_list, list) { - err = - device->me_device_lock_device(device, filep, - ME_LOCK_CHECK, - flags); - - if (err) - break; - } - - if (!err) - me_filep = filep; - } - - break; - - case ME_LOCK_RELEASE: - if ((me_filep != NULL) && (me_filep != filep)) { - err = ME_ERRNO_SUCCESS; - } else { - list_for_each_entry(device, &me_device_list, list) { - device->me_device_lock_device(device, filep, - ME_LOCK_RELEASE, - flags); - } - - me_filep = NULL; - } - - break; - - default: - PERROR("Invalid lock specified.\n"); - - err = ME_ERRNO_INVALID_LOCK; - - break; - } - - spin_unlock(&me_lock); - - up_read(&me_rwsem); - - return err; -} - -static int me_lock_driver(struct file *filep, me_lock_driver_t *arg) -{ - int err = 0; - - me_lock_driver_t lock; - - PDEBUG("executed.\n"); - - err = copy_from_user(&lock, arg, sizeof(me_lock_driver_t)); - - if (err) { - PERROR("Can't copy arguments to kernel space.\n"); - return -EFAULT; - } - - lock.errno = lock_driver(filep, lock.lock, lock.flags); - - err = copy_to_user(arg, &lock, sizeof(me_lock_driver_t)); - - if (err) { - PERROR("Can't copy query back to user space.\n"); - return -EFAULT; - } - - return ME_ERRNO_SUCCESS; -} - -static int me_open(struct inode *inode_ptr, struct file *filep) -{ - - PDEBUG("executed.\n"); - // Nothing to do here. - return 0; -} - -static int me_release(struct inode *inode_ptr, struct file *filep) -{ - - PDEBUG("executed.\n"); - lock_driver(filep, ME_LOCK_RELEASE, ME_LOCK_DRIVER_NO_FLAGS); - - return 0; -} - -static int me_query_version_main_driver(struct file *filep, - me_query_version_main_driver_t *arg) -{ - int err; - me_query_version_main_driver_t karg; - - PDEBUG("executed.\n"); - - karg.version = ME_VERSION_DRIVER; - karg.errno = ME_ERRNO_SUCCESS; - - err = copy_to_user(arg, &karg, sizeof(me_query_version_main_driver_t)); - - if (err) { - PERROR("Can't copy query back to user space.\n"); - return -EFAULT; - } - - return 0; -} - -static int me_config_load_device(struct file *filep, - me_cfg_device_entry_t *karg, int device_no) -{ - - int err = ME_ERRNO_SUCCESS; - int k = 0; - - struct list_head *pos = NULL; - me_device_t *device = NULL; - - PDEBUG("executed.\n"); - - list_for_each(pos, &me_device_list) { - if (k == device_no) { - device = list_entry(pos, me_device_t, list); - break; - } - - k++; - } - - if (pos == &me_device_list) { - PERROR("Invalid device number specified.\n"); - return ME_ERRNO_INVALID_DEVICE; - } else { - spin_lock(&me_lock); - - if ((me_filep != NULL) && (me_filep != filep)) { - spin_unlock(&me_lock); - PERROR("Resource is locked by another process.\n"); - return ME_ERRNO_LOCKED; - } else { - me_count++; - spin_unlock(&me_lock); - - err = - device->me_device_config_load(device, filep, karg); - - spin_lock(&me_lock); - me_count--; - spin_unlock(&me_lock); - } - } - - return err; -} - -static int me_config_load(struct file *filep, me_config_load_t *arg) -{ - int err; - int i; - me_config_load_t cfg_setup; - me_config_load_t karg_cfg_setup; - - struct list_head *pos = NULL; - - struct list_head new_list; - me_device_t *o_device; - me_device_t *n_device; - int o_vendor_id; - int o_device_id; - int o_serial_no; - int o_bus_type; - int o_bus_no; - int o_dev_no; - int o_func_no; - int o_plugged; - - PDEBUG("executed.\n"); - - // Copy argument to kernel space. - err = copy_from_user(&karg_cfg_setup, arg, sizeof(me_config_load_t)); - - if (err) { - PERROR("Can't copy arguments to kernel space.\n"); - return -EFAULT; - } - // Allocate kernel buffer for device list. - cfg_setup.device_list = - kmalloc(sizeof(me_cfg_device_entry_t) * karg_cfg_setup.count, - GFP_KERNEL); - - if (!cfg_setup.device_list) { - PERROR("Can't get buffer %li for device list.\n", - sizeof(me_cfg_device_entry_t) * karg_cfg_setup.count); - return -ENOMEM; - } - // Copy device list to kernel space. - err = - copy_from_user(cfg_setup.device_list, karg_cfg_setup.device_list, - sizeof(me_cfg_device_entry_t) * - karg_cfg_setup.count); - - if (err) { - PERROR("Can't copy device list to kernel space.\n"); - kfree(cfg_setup.device_list); - return -EFAULT; - } - - cfg_setup.count = karg_cfg_setup.count; - - INIT_LIST_HEAD(&new_list); - - down_write(&me_rwsem); - - spin_lock(&me_lock); - - if ((me_filep != NULL) && (me_filep != filep)) { - spin_unlock(&me_lock); - PERROR("Driver System is logged by another process.\n"); - karg_cfg_setup.errno = ME_ERRNO_LOCKED; - } else { - me_count++; - spin_unlock(&me_lock); - - for (i = 0; i < karg_cfg_setup.count; i++) { - PDEBUG("me_config_load() device=%d.\n", i); - if (cfg_setup.device_list[i].tcpip.access_type == - ME_ACCESS_TYPE_LOCAL) { - list_for_each(pos, &me_device_list) { - o_device = - list_entry(pos, me_device_t, list); - o_device-> - me_device_query_info_device - (o_device, &o_vendor_id, - &o_device_id, &o_serial_no, - &o_bus_type, &o_bus_no, &o_dev_no, - &o_func_no, &o_plugged); - - if (cfg_setup.device_list[i].info. - hw_location.bus_type == - ME_BUS_TYPE_PCI) { - if (((o_vendor_id == - cfg_setup.device_list[i]. - info.vendor_id) - && (o_device_id == - cfg_setup. - device_list[i].info. - device_id) - && (o_serial_no == - cfg_setup. - device_list[i].info. - serial_no) - && (o_bus_type == - cfg_setup. - device_list[i].info. - hw_location.bus_type)) - || - ((o_vendor_id == - cfg_setup.device_list[i]. - info.vendor_id) - && (o_device_id == - cfg_setup. - device_list[i].info. - device_id) - && (o_bus_type == - cfg_setup. - device_list[i].info. - hw_location.bus_type) - && (o_bus_no == - cfg_setup. - device_list[i].info. - hw_location.pci.bus_no) - && (o_dev_no == - cfg_setup. - device_list[i].info. - hw_location.pci. - device_no) - && (o_func_no == - cfg_setup. - device_list[i].info. - hw_location.pci. - function_no))) { - list_move_tail(pos, - &new_list); - break; - } - } -/* - else if (cfg_setup.device_list[i].info.hw_location.bus_type == ME_BUS_TYPE_USB) - { - if (((o_vendor_id == cfg_setup.device_list[i].info.vendor_id) && - (o_device_id == cfg_setup.device_list[i].info.device_id) && - (o_serial_no == cfg_setup.device_list[i].info.serial_no) && - (o_bus_type == cfg_setup.device_list[i].info.hw_location.bus_type)) || - ((o_vendor_id == cfg_setup.device_list[i].info.vendor_id) && - (o_device_id == cfg_setup.device_list[i].info.device_id) && - (o_bus_type == cfg_setup.device_list[i].info.hw_location.bus_type) && - (o_bus_no == cfg_setup.device_list[i].info.hw_location.usb.root_hub_no))) - { - list_move_tail(pos, &new_list); - break; - } - } -*/ - else { - PERROR("Wrong bus type: %d.\n", - cfg_setup.device_list[i]. - info.hw_location. - bus_type); - } - } - - if (pos == &me_device_list) { // Device is not already in the list - if (cfg_setup.device_list[i].info. - hw_location.bus_type == - ME_BUS_TYPE_PCI) { - n_device = - get_dummy_instance - (cfg_setup.device_list[i]. - info.vendor_id, - cfg_setup.device_list[i]. - info.device_id, - cfg_setup.device_list[i]. - info.serial_no, - cfg_setup.device_list[i]. - info.hw_location.bus_type, - cfg_setup.device_list[i]. - info.hw_location.pci. - bus_no, - cfg_setup.device_list[i]. - info.hw_location.pci. - device_no, - cfg_setup.device_list[i]. - info.hw_location.pci. - function_no); - - if (!n_device) { - PERROR - ("Can't get dummy instance.\n"); - kfree(cfg_setup. - device_list); - spin_lock(&me_lock); - me_count--; - spin_unlock(&me_lock); - up_write(&me_rwsem); - return -EFAULT; - } - - list_add_tail(&n_device->list, - &new_list); - } -/* - else if (cfg_setup.device_list[i].info.hw_location.bus_type == ME_BUS_TYPE_USB) - { - n_device = get_dummy_instance( - cfg_setup.device_list[i].info.vendor_id, - cfg_setup.device_list[i].info.device_id, - cfg_setup.device_list[i].info.serial_no, - cfg_setup.device_list[i].info.hw_location.bus_type, - cfg_setup.device_list[i].info.hw_location.usb.root_hub_no, - 0, - 0); - - if (!n_device) - { - PERROR("Can't get dummy instance.\n"); - kfree(cfg_setup.device_list); - spin_lock(&me_lock); - me_count--; - spin_unlock(&me_lock); - up_write(&me_rwsem); - return -EFAULT; - } - - list_add_tail(&n_device->list, &new_list); - } -*/ - } - } else { - n_device = get_dummy_instance(0, - 0, 0, 0, 0, 0, 0); - - if (!n_device) { - PERROR("Can't get dummy instance.\n"); - kfree(cfg_setup.device_list); - spin_lock(&me_lock); - me_count--; - spin_unlock(&me_lock); - up_write(&me_rwsem); - return -EFAULT; - } - - list_add_tail(&n_device->list, &new_list); - } - } - - while (!list_empty(&me_device_list)) { - o_device = - list_entry(me_device_list.next, me_device_t, list); - o_device->me_device_query_info_device(o_device, - &o_vendor_id, - &o_device_id, - &o_serial_no, - &o_bus_type, - &o_bus_no, - &o_dev_no, - &o_func_no, - &o_plugged); - - if (o_plugged == ME_PLUGGED_IN) { - list_move_tail(me_device_list.next, &new_list); - } else { - list_del(me_device_list.next); - release_instance(o_device); - } - } - - // Move temporary new list to global driver list. - list_splice(&new_list, &me_device_list); - - karg_cfg_setup.errno = ME_ERRNO_SUCCESS; - } - - for (i = 0; i < cfg_setup.count; i++) { - - karg_cfg_setup.errno = - me_config_load_device(filep, &cfg_setup.device_list[i], i); - if (karg_cfg_setup.errno) { - PERROR("me_config_load_device(%d)=%d\n", i, - karg_cfg_setup.errno); - break; - } - } - - spin_lock(&me_lock); - - me_count--; - spin_unlock(&me_lock); - up_write(&me_rwsem); - - err = copy_to_user(arg, &karg_cfg_setup, sizeof(me_config_load_t)); - - if (err) { - PERROR("Can't copy config list to user space.\n"); - kfree(cfg_setup.device_list); - return -EFAULT; - } - - kfree(cfg_setup.device_list); - return 0; -} - -static int me_io_stream_start(struct file *filep, me_io_stream_start_t *arg) -{ - int err; - int i, k; - - struct list_head *pos; - me_device_t *device; - me_io_stream_start_t karg; - meIOStreamStart_t *list; - - PDEBUG("executed.\n"); - - err = copy_from_user(&karg, arg, sizeof(me_io_stream_start_t)); - - if (err) { - PERROR("Can't copy arguments to kernel space.\n"); - return -EFAULT; - } - - karg.errno = ME_ERRNO_SUCCESS; - - list = kmalloc(sizeof(meIOStreamStart_t) * karg.count, GFP_KERNEL); - - if (!list) { - PERROR("Can't get buffer for start list.\n"); - return -ENOMEM; - } - - err = - copy_from_user(list, karg.start_list, - sizeof(meIOStreamStart_t) * karg.count); - - if (err) { - PERROR("Can't copy start list to kernel space.\n"); - kfree(list); - return -EFAULT; - } - - spin_lock(&me_lock); - - if ((me_filep != NULL) && (me_filep != filep)) { - spin_unlock(&me_lock); - PERROR("Driver System is logged by another process.\n"); - - for (i = 0; i < karg.count; i++) { - list[i].iErrno = ME_ERRNO_LOCKED; - } - } else { - me_count++; - spin_unlock(&me_lock); - - for (i = 0; i < karg.count; i++) { - down_read(&me_rwsem); - k = 0; - list_for_each(pos, &me_device_list) { - if (k == list[i].iDevice) { - device = - list_entry(pos, me_device_t, list); - break; - } - - k++; - } - - if (pos == &me_device_list) { - up_read(&me_rwsem); - PERROR("Invalid device number specified.\n"); - list[i].iErrno = ME_ERRNO_INVALID_DEVICE; - karg.errno = ME_ERRNO_INVALID_DEVICE; - break; - } else { - list[i].iErrno = - device->me_device_io_stream_start(device, - filep, - list[i]. - iSubdevice, - list[i]. - iStartMode, - list[i]. - iTimeOut, - list[i]. - iFlags); - - if (list[i].iErrno) { - up_read(&me_rwsem); - karg.errno = list[i].iErrno; - break; - } - } - - up_read(&me_rwsem); - } - - spin_lock(&me_lock); - - me_count--; - spin_unlock(&me_lock); - } - - err = copy_to_user(arg, &karg, sizeof(me_io_stream_start_t)); - - if (err) { - PERROR("Can't copy arguments to user space.\n"); - kfree(list); - return -EFAULT; - } - - err = - copy_to_user(karg.start_list, list, - sizeof(meIOStreamStart_t) * karg.count); - - if (err) { - PERROR("Can't copy start list to user space.\n"); - kfree(list); - return -EFAULT; - } - - kfree(list); - - return err; -} - -static int me_io_single(struct file *filep, me_io_single_t *arg) -{ - int err; - int i, k; - - struct list_head *pos; - me_device_t *device; - me_io_single_t karg; - meIOSingle_t *list; - - PDEBUG("executed.\n"); - - err = copy_from_user(&karg, arg, sizeof(me_io_single_t)); - - if (err) { - PERROR("Can't copy arguments to kernel space.\n"); - return -EFAULT; - } - - karg.errno = ME_ERRNO_SUCCESS; - - list = kmalloc(sizeof(meIOSingle_t) * karg.count, GFP_KERNEL); - - if (!list) { - PERROR("Can't get buffer for single list.\n"); - return -ENOMEM; - } - - err = - copy_from_user(list, karg.single_list, - sizeof(meIOSingle_t) * karg.count); - - if (err) { - PERROR("Can't copy single list to kernel space.\n"); - kfree(list); - return -EFAULT; - } - - spin_lock(&me_lock); - - if ((me_filep != NULL) && (me_filep != filep)) { - spin_unlock(&me_lock); - PERROR("Driver System is logged by another process.\n"); - - for (i = 0; i < karg.count; i++) { - list[i].iErrno = ME_ERRNO_LOCKED; - } - } else { - me_count++; - spin_unlock(&me_lock); - - for (i = 0; i < karg.count; i++) { - k = 0; - - down_read(&me_rwsem); - - list_for_each(pos, &me_device_list) { - if (k == list[i].iDevice) { - device = - list_entry(pos, me_device_t, list); - break; - } - - k++; - } - - if (pos == &me_device_list) { - up_read(&me_rwsem); - PERROR("Invalid device number specified.\n"); - list[i].iErrno = ME_ERRNO_INVALID_DEVICE; - karg.errno = ME_ERRNO_INVALID_DEVICE; - break; - } else { - if (list[i].iDir == ME_DIR_OUTPUT) { - list[i].iErrno = - device-> - me_device_io_single_write(device, - filep, - list[i]. - iSubdevice, - list[i]. - iChannel, - list[i]. - iValue, - list[i]. - iTimeOut, - list[i]. - iFlags); - - if (list[i].iErrno) { - up_read(&me_rwsem); - karg.errno = list[i].iErrno; - break; - } - } else if (list[i].iDir == ME_DIR_INPUT) { - list[i].iErrno = - device-> - me_device_io_single_read(device, - filep, - list[i]. - iSubdevice, - list[i]. - iChannel, - &list[i]. - iValue, - list[i]. - iTimeOut, - list[i]. - iFlags); - - if (list[i].iErrno) { - up_read(&me_rwsem); - karg.errno = list[i].iErrno; - break; - } - } else { - up_read(&me_rwsem); - PERROR - ("Invalid single direction specified.\n"); - list[i].iErrno = ME_ERRNO_INVALID_DIR; - karg.errno = ME_ERRNO_INVALID_DIR; - break; - } - } - - up_read(&me_rwsem); - } - - spin_lock(&me_lock); - - me_count--; - spin_unlock(&me_lock); - } - - err = copy_to_user(arg, &karg, sizeof(me_io_single_t)); - - if (err) { - PERROR("Can't copy arguments to user space.\n"); - return -EFAULT; - } - - err = - copy_to_user(karg.single_list, list, - sizeof(meIOSingle_t) * karg.count); - - if (err) { - PERROR("Can't copy single list to user space.\n"); - kfree(list); - return -EFAULT; - } - - kfree(list); - - return err; -} - -static int me_io_stream_config(struct file *filep, me_io_stream_config_t *arg) -{ - int err; - int k = 0; - - struct list_head *pos; - me_device_t *device; - me_io_stream_config_t karg; - meIOStreamConfig_t *list; - - PDEBUG("executed.\n"); - - err = copy_from_user(&karg, arg, sizeof(me_io_stream_config_t)); - - if (err) { - PERROR("Can't copy arguments to kernel space.\n"); - return -EFAULT; - } - - list = kmalloc(sizeof(meIOStreamConfig_t) * karg.count, GFP_KERNEL); - - if (!list) { - PERROR("Can't get buffer for config list.\n"); - return -ENOMEM; - } - - err = - copy_from_user(list, karg.config_list, - sizeof(meIOStreamConfig_t) * karg.count); - - if (err) { - PERROR("Can't copy config list to kernel space.\n"); - kfree(list); - return -EFAULT; - } - - spin_lock(&me_lock); - - if ((me_filep != NULL) && (me_filep != filep)) { - spin_unlock(&me_lock); - PERROR("Driver System is logged by another process.\n"); - karg.errno = ME_ERRNO_LOCKED; - } else { - me_count++; - spin_unlock(&me_lock); - - down_read(&me_rwsem); - - list_for_each(pos, &me_device_list) { - if (k == karg.device) { - device = list_entry(pos, me_device_t, list); - break; - } - - k++; - } - - if (pos == &me_device_list) { - PERROR("Invalid device number specified.\n"); - karg.errno = ME_ERRNO_INVALID_DEVICE; - } else { - karg.errno = - device->me_device_io_stream_config(device, filep, - karg.subdevice, - list, karg.count, - &karg.trigger, - karg. - fifo_irq_threshold, - karg.flags); - } - - up_read(&me_rwsem); - - spin_lock(&me_lock); - me_count--; - spin_unlock(&me_lock); - } - - err = copy_to_user(arg, &karg, sizeof(me_io_stream_config_t)); - - if (err) { - PERROR("Can't copy back to user space.\n"); - kfree(list); - return -EFAULT; - } - - kfree(list); - - return err; -} - -static int me_query_number_devices(struct file *filep, - me_query_number_devices_t *arg) -{ - int err; - me_query_number_devices_t karg; - - struct list_head *pos; - - PDEBUG("executed.\n"); - - karg.number = 0; - down_read(&me_rwsem); - list_for_each(pos, &me_device_list) { - karg.number++; - } - - up_read(&me_rwsem); - - karg.errno = ME_ERRNO_SUCCESS; - - err = copy_to_user(arg, &karg, sizeof(me_query_number_devices_t)); - - if (err) { - PERROR("Can't copy query back to user space.\n"); - return -EFAULT; - } - - return 0; -} - -static int me_io_stream_stop(struct file *filep, me_io_stream_stop_t *arg) -{ - int err; - int i, k; - - struct list_head *pos; - me_device_t *device; - me_io_stream_stop_t karg; - meIOStreamStop_t *list; - - PDEBUG("executed.\n"); - - err = copy_from_user(&karg, arg, sizeof(me_io_stream_stop_t)); - - if (err) { - PERROR("Can't copy arguments to kernel space.\n"); - return -EFAULT; - } - - karg.errno = ME_ERRNO_SUCCESS; - - list = kmalloc(sizeof(meIOStreamStop_t) * karg.count, GFP_KERNEL); - - if (!list) { - PERROR("Can't get buffer for stop list.\n"); - return -ENOMEM; - } - - err = - copy_from_user(list, karg.stop_list, - sizeof(meIOStreamStop_t) * karg.count); - - if (err) { - PERROR("Can't copy stop list to kernel space.\n"); - kfree(list); - return -EFAULT; - } - - spin_lock(&me_lock); - - if ((me_filep != NULL) && (me_filep != filep)) { - spin_unlock(&me_lock); - PERROR("Driver System is logged by another process.\n"); - - for (i = 0; i < karg.count; i++) { - list[i].iErrno = ME_ERRNO_LOCKED; - } - } else { - me_count++; - spin_unlock(&me_lock); - - for (i = 0; i < karg.count; i++) { - k = 0; - down_read(&me_rwsem); - list_for_each(pos, &me_device_list) { - if (k == list[i].iDevice) { - device = - list_entry(pos, me_device_t, list); - break; - } - - k++; - } - - if (pos == &me_device_list) { - up_read(&me_rwsem); - PERROR("Invalid device number specified.\n"); - list[i].iErrno = ME_ERRNO_INVALID_DEVICE; - karg.errno = ME_ERRNO_INVALID_DEVICE; - break; - } else { - list[i].iErrno = - device->me_device_io_stream_stop(device, - filep, - list[i]. - iSubdevice, - list[i]. - iStopMode, - list[i]. - iFlags); - - if (list[i].iErrno) { - up_read(&me_rwsem); - karg.errno = list[i].iErrno; - break; - } - } - - up_read(&me_rwsem); - } - - spin_lock(&me_lock); - - me_count--; - spin_unlock(&me_lock); - } - - err = copy_to_user(arg, &karg, sizeof(me_io_stream_stop_t)); - - if (err) { - PERROR("Can't copy arguments to user space.\n"); - return -EFAULT; - } - - err = - copy_to_user(karg.stop_list, list, - sizeof(meIOStreamStop_t) * karg.count); - - if (err) { - PERROR("Can't copy stop list to user space.\n"); - kfree(list); - return -EFAULT; - } - - kfree(list); - - return err; -} - -/* //me_probe_usb -static int me_probe_usb(struct usb_interface *interface, const struct usb_device_id *id) -{ - //int err; - //me_usb_constructor_t *constructor = NULL; - me_device_t *n_device = NULL; - - PDEBUG("executed.\n"); - - switch (id->idProduct) - { - case USB_DEVICE_ID_MEPHISTO_S1: - if((constructor = symbol_get(mephisto_s1_constructor)) == NULL){ - err = request_module(MEPHISTO_S1_NAME); - if(err){ - PERROR("Error while request for module %s.\n", MEPHISTO_S1_NAME); - return -ENODEV; - } - if((constructor = symbol_get(mephisto_s1_constructor)) == NULL){ - PERROR("Can't get %s driver module constructor.\n", MEPHISTO_S1_NAME); - return -ENODEV; - } - } - - if((n_device = (*constructor)(interface)) == NULL){ - symbol_put(mephisto_s1_constructor); - PERROR("Can't get device instance of %s driver module.\n", MEPHISTO_S1_NAME); - return -ENODEV; - } - - break; - - default: - PERROR("Invalid product id.\n"); - - return -EINVAL; - } - - return insert_to_device_list(n_device); -} -*/ - -/* //me_disconnect_usb -static void me_disconnect_usb(struct usb_interface *interface) -{ - - struct usb_device *device = interface_to_usbdev(interface); - int vendor_id = device->descriptor.idVendor; - int device_id = device->descriptor.idProduct; - int serial_no; - - sscanf(&device->serial[2], "%x", &serial_no); - - PDEBUG("executed.\n"); - - PINFO("Vendor id = 0x%08X\n", vendor_id); - PINFO("Device id = 0x%08X\n", device_id); - PINFO("Serial Number = 0x%08X\n", serial_no); - - replace_with_dummy(vendor_id, device_id, serial_no); -} -*/ - -static int me_ioctl(struct inode *inodep, - struct file *filep, unsigned int service, unsigned long arg) -{ - - PDEBUG("executed.\n"); - - if (_IOC_TYPE(service) != MEMAIN_MAGIC) { - PERROR("Invalid magic number.\n"); - return -ENOTTY; - } - - PDEBUG("service number: 0x%x.\n", service); - - switch (service) { - case ME_IO_IRQ_ENABLE: - return me_io_irq_start(filep, (me_io_irq_start_t *) arg); - - case ME_IO_IRQ_WAIT: - return me_io_irq_wait(filep, (me_io_irq_wait_t *) arg); - - case ME_IO_IRQ_DISABLE: - return me_io_irq_stop(filep, (me_io_irq_stop_t *) arg); - - case ME_IO_RESET_DEVICE: - return me_io_reset_device(filep, (me_io_reset_device_t *) arg); - - case ME_IO_RESET_SUBDEVICE: - return me_io_reset_subdevice(filep, - (me_io_reset_subdevice_t *) arg); - - case ME_IO_SINGLE_CONFIG: - return me_io_single_config(filep, - (me_io_single_config_t *) arg); - - case ME_IO_SINGLE: - return me_io_single(filep, (me_io_single_t *) arg); - - case ME_IO_STREAM_CONFIG: - return me_io_stream_config(filep, - (me_io_stream_config_t *) arg); - - case ME_IO_STREAM_NEW_VALUES: - return me_io_stream_new_values(filep, - (me_io_stream_new_values_t *) - arg); - - case ME_IO_STREAM_READ: - return me_io_stream_read(filep, (me_io_stream_read_t *) arg); - - case ME_IO_STREAM_START: - return me_io_stream_start(filep, (me_io_stream_start_t *) arg); - - case ME_IO_STREAM_STATUS: - return me_io_stream_status(filep, - (me_io_stream_status_t *) arg); - - case ME_IO_STREAM_STOP: - return me_io_stream_stop(filep, (me_io_stream_stop_t *) arg); - - case ME_IO_STREAM_WRITE: - return me_io_stream_write(filep, (me_io_stream_write_t *) arg); - - case ME_LOCK_DRIVER: - return me_lock_driver(filep, (me_lock_driver_t *) arg); - - case ME_LOCK_DEVICE: - return me_lock_device(filep, (me_lock_device_t *) arg); - - case ME_LOCK_SUBDEVICE: - return me_lock_subdevice(filep, (me_lock_subdevice_t *) arg); - - case ME_QUERY_INFO_DEVICE: - return me_query_info_device(filep, - (me_query_info_device_t *) arg); - - case ME_QUERY_DESCRIPTION_DEVICE: - return me_query_description_device(filep, - (me_query_description_device_t - *) arg); - - case ME_QUERY_NAME_DEVICE: - return me_query_name_device(filep, - (me_query_name_device_t *) arg); - - case ME_QUERY_NAME_DEVICE_DRIVER: - return me_query_name_device_driver(filep, - (me_query_name_device_driver_t - *) arg); - - case ME_QUERY_NUMBER_DEVICES: - return me_query_number_devices(filep, - (me_query_number_devices_t *) - arg); - - case ME_QUERY_NUMBER_SUBDEVICES: - return me_query_number_subdevices(filep, - (me_query_number_subdevices_t - *) arg); - - case ME_QUERY_NUMBER_CHANNELS: - return me_query_number_channels(filep, - (me_query_number_channels_t *) - arg); - - case ME_QUERY_NUMBER_RANGES: - return me_query_number_ranges(filep, - (me_query_number_ranges_t *) arg); - - case ME_QUERY_RANGE_BY_MIN_MAX: - return me_query_range_by_min_max(filep, - (me_query_range_by_min_max_t *) - arg); - - case ME_QUERY_RANGE_INFO: - return me_query_range_info(filep, - (me_query_range_info_t *) arg); - - case ME_QUERY_SUBDEVICE_BY_TYPE: - return me_query_subdevice_by_type(filep, - (me_query_subdevice_by_type_t - *) arg); - - case ME_QUERY_SUBDEVICE_TYPE: - return me_query_subdevice_type(filep, - (me_query_subdevice_type_t *) - arg); - - case ME_QUERY_SUBDEVICE_CAPS: - return me_query_subdevice_caps(filep, - (me_query_subdevice_caps_t *) - arg); - - case ME_QUERY_SUBDEVICE_CAPS_ARGS: - return me_query_subdevice_caps_args(filep, - (me_query_subdevice_caps_args_t - *) arg); - - case ME_QUERY_TIMER: - return me_query_timer(filep, (me_query_timer_t *) arg); - - case ME_QUERY_VERSION_MAIN_DRIVER: - return me_query_version_main_driver(filep, - (me_query_version_main_driver_t - *) arg); - - case ME_QUERY_VERSION_DEVICE_DRIVER: - return me_query_version_device_driver(filep, - (me_query_version_device_driver_t - *) arg); - - case ME_CONFIG_LOAD: - return me_config_load(filep, (me_config_load_t *) arg); - } - - PERROR("Invalid ioctl number.\n"); - return -ENOTTY; -} - -static struct miscdevice me_miscdev = { - .minor = MISC_DYNAMIC_MINOR, - .name = MEMAIN_NAME, - .fops = &me_file_operations, -}; - -// Init and exit of module. -static int memain_init(void) -{ - int result = 0; - - PDEBUG("executed.\n"); - - // Register pci driver. This will return 0 if the PCI subsystem is not available. - result = pci_register_driver(&me_pci_driver); - - if (result < 0) { - PERROR("Can't register pci driver.\n"); - goto INIT_ERROR_1; - } - -/* - // Register usb driver. This will return -ENODEV if no USB subsystem is available. - result = usb_register(&me_usb_driver); - - if (result) - { - if (result == -ENODEV) - { - PERROR("No USB subsystem available.\n"); - } - else - { - PERROR("Can't register usb driver.\n"); - goto INIT_ERROR_2; - } - } -*/ - result = misc_register(&me_miscdev); - if (result < 0) { - printk(KERN_ERR MEMAIN_NAME ": can't register misc device\n"); - goto INIT_ERROR_3; - } - - return 0; - - INIT_ERROR_3: -// usb_deregister(&me_usb_driver); - -//INIT_ERROR_2: - pci_unregister_driver(&me_pci_driver); - clear_device_list(); - - INIT_ERROR_1: - return result; -} - -static void __exit memain_exit(void) -{ - PDEBUG("executed.\n"); - - misc_deregister(&me_miscdev); - pci_unregister_driver(&me_pci_driver); -// usb_deregister(&me_usb_driver); - clear_device_list(); -} - -module_init(memain_init); -module_exit(memain_exit); - -// Administrative stuff for modinfo. -MODULE_AUTHOR - ("Guenter Gebhardt <g.gebhardt@meilhaus.de> & Krzysztof Gantzke <k.gantzke@meilhaus.de>"); -MODULE_DESCRIPTION("Central module for Meilhaus Driver System."); -MODULE_SUPPORTED_DEVICE("Meilhaus PCI/cPCI boards."); -MODULE_LICENSE("GPL"); |