diff options
author | merge <null@invalid> | 2009-01-22 13:55:32 +0000 |
---|---|---|
committer | Andy Green <agreen@octopus.localdomain> | 2009-01-22 13:55:32 +0000 |
commit | aa6f5ffbdba45aa8e19e5048648fc6c7b25376d3 (patch) | |
tree | fbb786d0ac6f8a774fd834e9ce951197e60fbffa /drivers/staging/meilhaus/medevice.c | |
parent | f2d78193eae5dccd3d588d2c8ea0866efc368332 (diff) |
MERGE-via-pending-tracking-hist-MERGE-via-stable-tracking-MERGE-via-mokopatches-tracking-fix-stray-endmenu-patch-1232632040-1232632141
pending-tracking-hist top was MERGE-via-stable-tracking-MERGE-via-mokopatches-tracking-fix-stray-endmenu-patch-1232632040-1232632141 / fdf777a63bcb59e0dfd78bfe2c6242e01f6d4eb9 ... parent commitmessage:
From: merge <null@invalid>
MERGE-via-stable-tracking-hist-MERGE-via-mokopatches-tracking-fix-stray-endmenu-patch-1232632040
stable-tracking-hist top was MERGE-via-mokopatches-tracking-fix-stray-endmenu-patch-1232632040 / 90463bfd2d5a3c8b52f6e6d71024a00e052b0ced ... parent commitmessage:
From: merge <null@invalid>
MERGE-via-mokopatches-tracking-hist-fix-stray-endmenu-patch
mokopatches-tracking-hist top was fix-stray-endmenu-patch / 3630e0be570de8057e7f8d2fe501ed353cdf34e6 ... parent commitmessage:
From: Andy Green <andy@openmoko.com>
fix-stray-endmenu.patch
Signed-off-by: Andy Green <andy@openmoko.com>
Diffstat (limited to 'drivers/staging/meilhaus/medevice.c')
-rw-r--r-- | drivers/staging/meilhaus/medevice.c | 1740 |
1 files changed, 1740 insertions, 0 deletions
diff --git a/drivers/staging/meilhaus/medevice.c b/drivers/staging/meilhaus/medevice.c new file mode 100644 index 00000000000..8f62e16c7a3 --- /dev/null +++ b/drivers/staging/meilhaus/medevice.c @@ -0,0 +1,1740 @@ +/** + * @file medevice.c + * + * @brief Meilhaus device base class. + * @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. + */ + +#include "mecommon.h" +#include "meinternal.h" +#include "medefines.h" +#include "meerror.h" + +#include "medebug.h" +#include "medevice.h" + +#ifndef __KERNEL__ +# define __KERNEL__ +#endif + +static int me_device_io_irq_start(struct me_device *device, + struct file *filep, + int subdevice, + int channel, + int irq_source, + int irq_edge, int irq_arg, int flags) +{ + int err = ME_ERRNO_SUCCESS; + me_subdevice_t *s; + + PDEBUG("executed.\n"); + + // Check subdevice index. + if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { + PERROR("Invalid subdevice.\n"); + return ME_ERRNO_INVALID_SUBDEVICE; + } + // Enter device. + err = me_dlock_enter(&device->dlock, filep); + + if (err) { + PERROR("Cannot enter device.\n"); + return err; + } + // Get subdevice instance. + s = me_slist_get_subdevice(&device->slist, subdevice); + + if (s) { + // Call subdevice method. + err = s->me_subdevice_io_irq_start(s, + filep, + channel, + irq_source, + irq_edge, irq_arg, flags); + } else { + // Something really bad happened. + PERROR("Cannot get subdevice instance.\n"); + err = ME_ERRNO_INTERNAL; + } + + // Exit device. + me_dlock_exit(&device->dlock, filep); + + return err; +} + +static int me_device_io_irq_wait(struct me_device *device, + struct file *filep, + int subdevice, + int channel, + int *irq_count, + int *value, int time_out, int flags) +{ + int err = ME_ERRNO_SUCCESS; + me_subdevice_t *s; + + PDEBUG("executed.\n"); + + // Check subdevice index. + if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { + PERROR("Invalid subdevice.\n"); + return ME_ERRNO_INVALID_SUBDEVICE; + } + // Enter device. + err = me_dlock_enter(&device->dlock, filep); + + if (err) { + PERROR("Cannot enter device.\n"); + return err; + } + // Get subdevice instance. + s = me_slist_get_subdevice(&device->slist, subdevice); + + if (s) { + // Call subdevice method. + err = s->me_subdevice_io_irq_wait(s, + filep, + channel, + irq_count, + value, time_out, flags); + } else { + // Something really bad happened. + PERROR("Cannot get subdevice instance.\n"); + err = ME_ERRNO_INTERNAL; + } + + // Exit device. + me_dlock_exit(&device->dlock, filep); + + return err; +} + +static int me_device_io_irq_stop(struct me_device *device, + struct file *filep, + int subdevice, int channel, int flags) +{ + int err = ME_ERRNO_SUCCESS; + me_subdevice_t *s; + + PDEBUG("executed.\n"); + + // Check subdevice index. + if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { + PERROR("Invalid subdevice.\n"); + return ME_ERRNO_INVALID_SUBDEVICE; + } + // Enter device. + err = me_dlock_enter(&device->dlock, filep); + + if (err) { + PERROR("Cannot enter device.\n"); + return err; + } + // Get subdevice instance. + s = me_slist_get_subdevice(&device->slist, subdevice); + + if (s) { + // Call subdevice method. + err = s->me_subdevice_io_irq_stop(s, filep, channel, flags); + } else { + // Something really bad happened. + PERROR("Cannot get subdevice instance.\n"); + err = ME_ERRNO_INTERNAL; + } + + // Exit device. + me_dlock_exit(&device->dlock, filep); + + return err; +} + +static int me_device_io_reset_device(struct me_device *device, + struct file *filep, int flags) +{ + int err = ME_ERRNO_SUCCESS; + me_subdevice_t *s; + int i, n; + + PDEBUG("executed.\n"); + + /* Get the number of subdevices. */ + n = me_slist_get_number_subdevices(&device->slist); + + // Enter device. + err = me_dlock_enter(&device->dlock, filep); + + if (err) { + PERROR("Cannot enter device.\n"); + return err; + } + + /* Reset every subdevice in list. */ + for (i = 0; i < n; i++) { + s = me_slist_get_subdevice(&device->slist, i); + err = s->me_subdevice_io_reset_subdevice(s, filep, flags); + + if (err) { + PERROR("Cannot reset subdevice.\n"); + break; + } + } + + // Exit device. + me_dlock_exit(&device->dlock, filep); + + return err; +} + +static int me_device_io_reset_subdevice(struct me_device *device, + struct file *filep, + int subdevice, int flags) +{ + int err = ME_ERRNO_SUCCESS; + me_subdevice_t *s; + + PDEBUG("executed.\n"); + + // Check subdevice index. + + if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { + PERROR("Invalid subdevice.\n"); + return ME_ERRNO_INVALID_SUBDEVICE; + } + // Enter device. + err = me_dlock_enter(&device->dlock, filep); + + if (err) { + PERROR("Cannot enter device.\n"); + return err; + } + // Get subdevice instance. + s = me_slist_get_subdevice(&device->slist, subdevice); + + if (s) { + // Call subdevice method. + err = s->me_subdevice_io_reset_subdevice(s, filep, flags); + } else { + // Something really bad happened. + PERROR("Cannot get subdevice instance.\n"); + err = ME_ERRNO_INTERNAL; + } + + // Exit device. + me_dlock_exit(&device->dlock, filep); + + return err; +} + +static int me_device_io_single_config(struct me_device *device, + struct file *filep, + int subdevice, + int channel, + int single_config, + int ref, + int trig_chan, + int trig_type, int trig_edge, int flags) +{ + int err = ME_ERRNO_SUCCESS; + me_subdevice_t *s; + + PDEBUG("executed.\n"); + + // Check subdevice index. + + if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { + PERROR("Invalid subdevice.\n"); + return ME_ERRNO_INVALID_SUBDEVICE; + } + // Enter device. + err = me_dlock_enter(&device->dlock, filep); + + if (err) { + PERROR("Cannot enter device.\n"); + return err; + } + // Get subdevice instance. + s = me_slist_get_subdevice(&device->slist, subdevice); + + if (s) { + // Call subdevice method. + err = s->me_subdevice_io_single_config(s, + filep, + channel, + single_config, + ref, + trig_chan, + trig_type, + trig_edge, flags); + } else { + // Something really bad happened. + PERROR("Cannot get subdevice instance.\n"); + err = ME_ERRNO_INTERNAL; + } + + // Exit device. + me_dlock_exit(&device->dlock, filep); + + return err; +} + +static int me_device_io_single_read(struct me_device *device, + struct file *filep, + int subdevice, + int channel, + int *value, int time_out, int flags) +{ + int err = ME_ERRNO_SUCCESS; + me_subdevice_t *s; + + PDEBUG("executed.\n"); + + // Check subdevice index. + + if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { + PERROR("Invalid subdevice.\n"); + return ME_ERRNO_INVALID_SUBDEVICE; + } + // Enter device. + err = me_dlock_enter(&device->dlock, filep); + + if (err) { + PERROR("Cannot enter device.\n"); + return err; + } + // Get subdevice instance. + s = me_slist_get_subdevice(&device->slist, subdevice); + + if (s) { + // Call subdevice method. + err = s->me_subdevice_io_single_read(s, + filep, + channel, + value, time_out, flags); + } else { + // Something really bad happened. + PERROR("Cannot get subdevice instance.\n"); + err = ME_ERRNO_INTERNAL; + } + + // Exit device. + me_dlock_exit(&device->dlock, filep); + + return err; +} + +static int me_device_io_single_write(struct me_device *device, + struct file *filep, + int subdevice, + int channel, + int value, int time_out, int flags) +{ + int err = ME_ERRNO_SUCCESS; + me_subdevice_t *s; + + PDEBUG("executed.\n"); + + // Check subdevice index. + + if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { + PERROR("Invalid subdevice.\n"); + return ME_ERRNO_INVALID_SUBDEVICE; + } + // Enter device. + err = me_dlock_enter(&device->dlock, filep); + + if (err) { + PERROR("Cannot enter device.\n"); + return err; + } + // Get subdevice instance. + s = me_slist_get_subdevice(&device->slist, subdevice); + + if (s) { + // Call subdevice method. + err = s->me_subdevice_io_single_write(s, + filep, + channel, + value, time_out, flags); + } else { + // Something really bad happened. + PERROR("Cannot get subdevice instance.\n"); + err = ME_ERRNO_INTERNAL; + } + + // Exit device. + me_dlock_exit(&device->dlock, filep); + + return err; +} + +static int me_device_io_stream_config(struct me_device *device, + struct file *filep, + int subdevice, + meIOStreamConfig_t * config_list, + int count, + meIOStreamTrigger_t * trigger, + int fifo_irq_threshold, int flags) +{ + int err = ME_ERRNO_SUCCESS; + me_subdevice_t *s; + + PDEBUG("executed.\n"); + + // Check subdevice index. + + if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { + PERROR("Invalid subdevice.\n"); + return ME_ERRNO_INVALID_SUBDEVICE; + } + // Enter device. + err = me_dlock_enter(&device->dlock, filep); + + if (err) { + PERROR("Cannot enter device.\n"); + return err; + } + // Get subdevice instance. + s = me_slist_get_subdevice(&device->slist, subdevice); + + if (s) { + // Call subdevice method. + err = s->me_subdevice_io_stream_config(s, + filep, + config_list, + count, + trigger, + fifo_irq_threshold, + flags); + } else { + // Something really bad happened. + PERROR("Cannot get subdevice instance.\n"); + err = ME_ERRNO_INTERNAL; + } + + // Exit device. + me_dlock_exit(&device->dlock, filep); + + return err; +} + +static int me_device_io_stream_new_values(struct me_device *device, + struct file *filep, + int subdevice, + int time_out, int *count, int flags) +{ + int err = ME_ERRNO_SUCCESS; + me_subdevice_t *s; + + PDEBUG("executed.\n"); + + // Check subdevice index. + + if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { + PERROR("Invalid subdevice.\n"); + return ME_ERRNO_INVALID_SUBDEVICE; + } + // Enter device. + err = me_dlock_enter(&device->dlock, filep); + + if (err) { + PERROR("Cannot enter device.\n"); + return err; + } + // Get subdevice instance. + s = me_slist_get_subdevice(&device->slist, subdevice); + + if (s) { + // Call subdevice method. + err = s->me_subdevice_io_stream_new_values(s, + filep, + time_out, + count, flags); + } else { + // Something really bad happened. + PERROR("Cannot get subdevice instance.\n"); + err = ME_ERRNO_INTERNAL; + } + + // Exit device. + me_dlock_exit(&device->dlock, filep); + + return err; +} + +static int me_device_io_stream_read(struct me_device *device, + struct file *filep, + int subdevice, + int read_mode, + int *values, int *count, int flags) +{ + int err = ME_ERRNO_SUCCESS; + me_subdevice_t *s; + + PDEBUG("executed.\n"); + + // Check subdevice index. + + if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { + PERROR("Invalid subdevice.\n"); + return ME_ERRNO_INVALID_SUBDEVICE; + } + // Enter device. + err = me_dlock_enter(&device->dlock, filep); + + if (err) { + PERROR("Cannot enter device.\n"); + return err; + } + // Get subdevice instance. + s = me_slist_get_subdevice(&device->slist, subdevice); + + if (s) { + // Call subdevice method. + err = s->me_subdevice_io_stream_read(s, + filep, + read_mode, + values, count, flags); + } else { + // Something really bad happened. + PERROR("Cannot get subdevice instance.\n"); + err = ME_ERRNO_INTERNAL; + } + + // Exit device. + me_dlock_exit(&device->dlock, filep); + + return err; +} + +static int me_device_io_stream_start(struct me_device *device, + struct file *filep, + int subdevice, + int start_mode, int time_out, int flags) +{ + int err = ME_ERRNO_SUCCESS; + me_subdevice_t *s; + + PDEBUG("executed.\n"); + + // Check subdevice index. + + if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { + PERROR("Invalid subdevice.\n"); + return ME_ERRNO_INVALID_SUBDEVICE; + } + // Enter device. + err = me_dlock_enter(&device->dlock, filep); + + if (err) { + PERROR("Cannot enter device.\n"); + return err; + } + // Get subdevice instance. + s = me_slist_get_subdevice(&device->slist, subdevice); + + if (s) { + // Call subdevice method. + err = s->me_subdevice_io_stream_start(s, + filep, + start_mode, + time_out, flags); + } else { + // Something really bad happened. + PERROR("Cannot get subdevice instance.\n"); + err = ME_ERRNO_INTERNAL; + } + + // Exit device. + me_dlock_exit(&device->dlock, filep); + + return err; +} + +static int me_device_io_stream_status(struct me_device *device, + struct file *filep, + int subdevice, + int wait, + int *status, int *count, int flags) +{ + int err = ME_ERRNO_SUCCESS; + me_subdevice_t *s; + + PDEBUG("executed.\n"); + + // Check subdevice index. + + if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { + PERROR("Invalid subdevice.\n"); + return ME_ERRNO_INVALID_SUBDEVICE; + } + // Enter device. + err = me_dlock_enter(&device->dlock, filep); + + if (err) { + PERROR("Cannot enter device.\n"); + return err; + } + // Get subdevice instance. + s = me_slist_get_subdevice(&device->slist, subdevice); + + if (s) { + // Call subdevice method. + err = s->me_subdevice_io_stream_status(s, + filep, + wait, + status, count, flags); + } else { + // Something really bad happened. + PERROR("Cannot get subdevice instance.\n"); + err = ME_ERRNO_INTERNAL; + } + + // Exit device. + me_dlock_exit(&device->dlock, filep); + + return err; +} + +static int me_device_io_stream_stop(struct me_device *device, + struct file *filep, + int subdevice, int stop_mode, int flags) +{ + int err = ME_ERRNO_SUCCESS; + me_subdevice_t *s; + + PDEBUG("executed.\n"); + + // Check subdevice index. + + if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { + PERROR("Invalid subdevice.\n"); + return ME_ERRNO_INVALID_SUBDEVICE; + } + // Enter device. + err = me_dlock_enter(&device->dlock, filep); + + if (err) { + PERROR("Cannot enter device.\n"); + return err; + } + // Get subdevice instance. + s = me_slist_get_subdevice(&device->slist, subdevice); + + if (s) { + // Call subdevice method. + err = s->me_subdevice_io_stream_stop(s, + filep, stop_mode, flags); + } else { + // Something really bad happened. + PERROR("Cannot get subdevice instance.\n"); + err = ME_ERRNO_INTERNAL; + } + + // Exit device. + me_dlock_exit(&device->dlock, filep); + + return err; +} + +static int me_device_io_stream_write(struct me_device *device, + struct file *filep, + int subdevice, + int write_mode, + int *values, int *count, int flags) +{ + int err = ME_ERRNO_SUCCESS; + me_subdevice_t *s; + + PDEBUG("executed.\n"); + + // Check subdevice index. + + if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { + PERROR("Invalid subdevice.\n"); + return ME_ERRNO_INVALID_SUBDEVICE; + } + // Enter device. + err = me_dlock_enter(&device->dlock, filep); + + if (err) { + PERROR("Cannot enter device.\n"); + return err; + } + // Get subdevice instance. + s = me_slist_get_subdevice(&device->slist, subdevice); + + if (s) { + // Call subdevice method. + err = s->me_subdevice_io_stream_write(s, + filep, + write_mode, + values, count, flags); + } else { + // Something really bad happened. + PERROR("Cannot get subdevice instance.\n"); + err = ME_ERRNO_INTERNAL; + } + + // Exit device. + me_dlock_exit(&device->dlock, filep); + + return err; +} + +static int me_device_lock_device(struct me_device *device, + struct file *filep, int lock, int flags) +{ + PDEBUG("executed.\n"); + + return me_dlock_lock(&device->dlock, + filep, lock, flags, &device->slist); +} + +static int me_device_lock_subdevice(struct me_device *device, + struct file *filep, + int subdevice, int lock, int flags) +{ + int err = ME_ERRNO_SUCCESS; + me_subdevice_t *s; + + PDEBUG("executed.\n"); + + // Check subdevice index. + + if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { + PERROR("Invalid subdevice.\n"); + return ME_ERRNO_INVALID_SUBDEVICE; + } + // Enter device. + err = me_dlock_enter(&device->dlock, filep); + + if (err) { + PERROR("Cannot enter device.\n"); + return err; + } + // Get subdevice instance. + s = me_slist_get_subdevice(&device->slist, subdevice); + + if (s) { + // Call subdevice method. + err = s->me_subdevice_lock_subdevice(s, filep, lock, flags); + } else { + // Something really bad happened. + PERROR("Cannot get subdevice instance.\n"); + err = ME_ERRNO_INTERNAL; + } + + // Exit device. + me_dlock_exit(&device->dlock, filep); + + return err; +} + +static int me_device_query_description_device(struct me_device *device, + char **description) +{ + PDEBUG("executed.\n"); + *description = device->device_description; + return ME_ERRNO_SUCCESS; +} + +static int me_device_query_info_device(struct me_device *device, + int *vendor_id, + int *device_id, + int *serial_no, + int *bus_type, + int *bus_no, + int *dev_no, int *func_no, int *plugged) +{ + PDEBUG("executed.\n"); + + if (device->bus_type == ME_BUS_TYPE_PCI) { + *vendor_id = device->info.pci.vendor_id; + *device_id = device->info.pci.device_id; + *serial_no = device->info.pci.serial_no; + *bus_type = ME_BUS_TYPE_PCI; + *bus_no = device->info.pci.pci_bus_no; + *dev_no = device->info.pci.pci_dev_no; + *func_no = device->info.pci.pci_func_no; + *plugged = ME_PLUGGED_IN; + } else { + *plugged = ME_PLUGGED_OUT; + } + return ME_ERRNO_SUCCESS; +} + +static int me_device_query_name_device(struct me_device *device, char **name) +{ + PDEBUG("executed.\n"); + *name = device->device_name; + return ME_ERRNO_SUCCESS; +} + +static int me_device_query_name_device_driver(struct me_device *device, + char **name) +{ + PDEBUG("executed.\n"); + *name = device->driver_name; + return ME_ERRNO_SUCCESS; +} + +static int me_device_query_number_subdevices(struct me_device *device, + int *number) +{ + PDEBUG("executed.\n"); + return me_slist_query_number_subdevices(&device->slist, number); +} + +static int me_device_query_number_channels(struct me_device *device, + int subdevice, int *number) +{ + int err = ME_ERRNO_SUCCESS; + me_subdevice_t *s; + + PDEBUG("executed.\n"); + + // Check subdevice index. + + if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { + PERROR("Invalid subdevice.\n"); + return ME_ERRNO_INVALID_SUBDEVICE; + } + // Get subdevice instance. + s = me_slist_get_subdevice(&device->slist, subdevice); + + if (s) { + // Call subdevice method. + err = s->me_subdevice_query_number_channels(s, number); + } else { + // Something really bad happened. + PERROR("Cannot get subdevice instance.\n"); + err = ME_ERRNO_INTERNAL; + } + + return err; +} + +static int me_device_query_number_ranges(struct me_device *device, + int subdevice, int unit, int *count) +{ + int err = ME_ERRNO_SUCCESS; + me_subdevice_t *s; + + PDEBUG("executed.\n"); + + // Check subdevice index. + + if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { + PERROR("Invalid subdevice.\n"); + return ME_ERRNO_INVALID_SUBDEVICE; + } + // Get subdevice instance. + s = me_slist_get_subdevice(&device->slist, subdevice); + + if (s) { + // Call subdevice method. + err = s->me_subdevice_query_number_ranges(s, unit, count); + } else { + // Something really bad happened. + PERROR("Cannot get subdevice instance.\n"); + err = ME_ERRNO_INTERNAL; + } + + return err; +} + +static int me_device_query_range_by_min_max(struct me_device *device, + int subdevice, + int unit, + int *min, + int *max, int *maxdata, int *range) +{ + int err = ME_ERRNO_SUCCESS; + me_subdevice_t *s; + + PDEBUG("executed.\n"); + + // Check subdevice index. + + if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { + PERROR("Invalid subdevice.\n"); + return ME_ERRNO_INVALID_SUBDEVICE; + } + // Get subdevice instance. + s = me_slist_get_subdevice(&device->slist, subdevice); + + if (s) { + // Call subdevice method. + err = s->me_subdevice_query_range_by_min_max(s, + unit, + min, + max, + maxdata, range); + } else { + // Something really bad happened. + PERROR("Cannot get subdevice instance.\n"); + err = ME_ERRNO_INTERNAL; + } + + return err; +} + +static int me_device_query_range_info(struct me_device *device, + int subdevice, + int range, + int *unit, + int *min, int *max, int *maxdata) +{ + int err = ME_ERRNO_SUCCESS; + me_subdevice_t *s; + + PDEBUG("executed.\n"); + + // Check subdevice index. + + if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { + PERROR("Invalid subdevice.\n"); + return ME_ERRNO_INVALID_SUBDEVICE; + } + // Get subdevice instance. + s = me_slist_get_subdevice(&device->slist, subdevice); + + if (s) { + // Call subdevice method. + err = s->me_subdevice_query_range_info(s, + range, + unit, min, max, maxdata); + } else { + // Something really bad happened. + PERROR("Cannot get subdevice instance.\n"); + err = ME_ERRNO_INTERNAL; + } + + return err; +} + +static int me_device_query_subdevice_by_type(struct me_device *device, + int start_subdevice, + int type, + int subtype, int *subdevice) +{ + PDEBUG("executed.\n"); + + return me_slist_get_subdevice_by_type(&device->slist, + start_subdevice, + type, subtype, subdevice); +} + +static int me_device_query_subdevice_type(struct me_device *device, + int subdevice, + int *type, int *subtype) +{ + int err = ME_ERRNO_SUCCESS; + me_subdevice_t *s; + + PDEBUG("executed.\n"); + + // Check subdevice index. + + if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { + PERROR("Invalid subdevice.\n"); + return ME_ERRNO_INVALID_SUBDEVICE; + } + // Get subdevice instance. + s = me_slist_get_subdevice(&device->slist, subdevice); + + if (s) { + // Call subdevice method. + err = s->me_subdevice_query_subdevice_type(s, type, subtype); + } else { + // Something really bad happened. + PERROR("Cannot get subdevice instance.\n"); + err = ME_ERRNO_INTERNAL; + } + + return err; +} + +static int me_device_query_subdevice_caps(struct me_device *device, + int subdevice, int *caps) +{ + int err = ME_ERRNO_SUCCESS; + me_subdevice_t *s; + + PDEBUG("executed.\n"); + + // Check subdevice index. + + if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { + PERROR("Invalid subdevice.\n"); + return ME_ERRNO_INVALID_SUBDEVICE; + } + // Get subdevice instance. + s = me_slist_get_subdevice(&device->slist, subdevice); + + if (s) { + // Call subdevice method. + err = s->me_subdevice_query_subdevice_caps(s, caps); + } else { + // Something really bad happened. + PERROR("Cannot get subdevice instance.\n"); + err = ME_ERRNO_INTERNAL; + } + + return err; +} + +static int me_device_query_subdevice_caps_args(struct me_device *device, + int subdevice, + int cap, int *args, int count) +{ + int err = ME_ERRNO_SUCCESS; + me_subdevice_t *s; + + PDEBUG("executed.\n"); + + // Check subdevice index. + + if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { + PERROR("Invalid subdevice.\n"); + return ME_ERRNO_INVALID_SUBDEVICE; + } + // Get subdevice instance. + s = me_slist_get_subdevice(&device->slist, subdevice); + + if (s) { + // Call subdevice method. + err = s->me_subdevice_query_subdevice_caps_args(s, + cap, + args, count); + } else { + // Something really bad happened. + PERROR("Cannot get subdevice instance.\n"); + err = ME_ERRNO_INTERNAL; + } + + return err; +} + +static int me_device_query_timer(struct me_device *device, + int subdevice, + int timer, + int *base_frequency, + uint64_t * min_ticks, uint64_t * max_ticks) +{ + int err = ME_ERRNO_SUCCESS; + me_subdevice_t *s; + + PDEBUG("executed.\n"); + + // Check subdevice index. + + if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { + PERROR("Invalid subdevice.\n"); + return ME_ERRNO_INVALID_SUBDEVICE; + } + // Get subdevice instance. + s = me_slist_get_subdevice(&device->slist, subdevice); + + if (s) { + // Call subdevice method. + err = s->me_subdevice_query_timer(s, + timer, + base_frequency, + min_ticks, max_ticks); + } else { + // Something really bad happened. + PERROR("Cannot get subdevice instance.\n"); + err = ME_ERRNO_INTERNAL; + } + + return err; +} + +static int me_device_query_version_device_driver(struct me_device *device, + int *version) +/** @todo Versions shold be read from driver. I must overwrite this function in each module. Here should be returned an error! +*/ +{ + PDEBUG("executed.\n"); + *version = ME_VERSION_DRIVER; + return ME_ERRNO_SUCCESS; +} + +static int me_device_config_load(struct me_device *device, struct file *filep, + me_cfg_device_entry_t * config) +{ + PDEBUG("executed.\n"); + return ME_ERRNO_SUCCESS; //If no need for config return success. +// return ME_ERRNO_NOT_SUPPORTED; +} + +static void me_device_destructor(me_device_t * me_device) +{ + PDEBUG("executed.\n"); + me_device_deinit(me_device); + kfree(me_device); +} + +/* //me_device_usb_init +int me_device_usb_init(me_device_t *me_device, struct usb_interface *interface) +{ + PDEBUG("executed.\n"); + return -1; +} +*/ + +static int get_device_descriptions(uint16_t device_id, + char **device_name, + char **device_description, + char **driver_name) +/** @todo This is wrong concept! Static table has too strong limitations! +* 'device_name' and 'driver_name' should be calculated from 'device_id' +* 'device_description' should be read from device or moved to user space and handled by library! +*/ +{ + PDEBUG("executed.\n"); + + switch (device_id) { + case PCI_DEVICE_ID_MEILHAUS_ME1000: + case PCI_DEVICE_ID_MEILHAUS_ME1000_A: + case PCI_DEVICE_ID_MEILHAUS_ME1000_B: + *device_name = ME1000_NAME_DEVICE_ME1000; + *device_description = ME1000_DESCRIPTION_DEVICE_ME1000; + *driver_name = ME1000_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME1400: + *device_name = ME1400_NAME_DEVICE_ME1400; + *device_description = ME1400_DESCRIPTION_DEVICE_ME1400; + *driver_name = ME1400_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME140A: + *device_name = ME1400_NAME_DEVICE_ME1400A; + *device_description = ME1400_DESCRIPTION_DEVICE_ME1400A; + *driver_name = ME1400_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME140B: + *device_name = ME1400_NAME_DEVICE_ME1400B; + *device_description = ME1400_DESCRIPTION_DEVICE_ME1400B; + *driver_name = ME1400_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME14E0: + *device_name = ME1400_NAME_DEVICE_ME1400E; + *device_description = ME1400_DESCRIPTION_DEVICE_ME1400E; + *driver_name = ME1400_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME14EA: + *device_name = ME1400_NAME_DEVICE_ME1400EA; + *device_description = ME1400_DESCRIPTION_DEVICE_ME1400EA; + *driver_name = ME1400_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME14EB: + *device_name = ME1400_NAME_DEVICE_ME1400EB; + *device_description = ME1400_DESCRIPTION_DEVICE_ME1400EB; + *driver_name = ME1400_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME140C: + *device_name = ME1400_NAME_DEVICE_ME1400C; + *device_description = ME1400_DESCRIPTION_DEVICE_ME1400C; + *driver_name = ME1400_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME140D: + *device_name = ME1400_NAME_DEVICE_ME1400D; + *device_description = ME1400_DESCRIPTION_DEVICE_ME1400D; + *driver_name = ME1400_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME1600_4U: + *device_name = ME1600_NAME_DEVICE_ME16004U; + *device_description = ME1600_DESCRIPTION_DEVICE_ME16004U; + *driver_name = ME1600_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME1600_8U: + *device_name = ME1600_NAME_DEVICE_ME16008U; + *device_description = ME1600_DESCRIPTION_DEVICE_ME16008U; + *driver_name = ME1600_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME1600_12U: + *device_name = ME1600_NAME_DEVICE_ME160012U; + *device_description = ME1600_DESCRIPTION_DEVICE_ME160012U; + *driver_name = ME1600_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME1600_16U: + *device_name = ME1600_NAME_DEVICE_ME160016U; + *device_description = ME1600_DESCRIPTION_DEVICE_ME160016U; + *driver_name = ME1600_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME1600_16U_8I: + *device_name = ME1600_NAME_DEVICE_ME160016U8I; + *device_description = ME1600_DESCRIPTION_DEVICE_ME160016U8I; + *driver_name = ME1600_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME4610: + *device_name = ME4600_NAME_DEVICE_ME4610; + *device_description = ME4600_DESCRIPTION_DEVICE_ME4610; + *driver_name = ME4600_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME4650: + *device_name = ME4600_NAME_DEVICE_ME4650; + *device_description = ME4600_DESCRIPTION_DEVICE_ME4650; + *driver_name = ME4600_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME4660: + *device_name = ME4600_NAME_DEVICE_ME4660; + *device_description = ME4600_DESCRIPTION_DEVICE_ME4660; + *driver_name = ME4600_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME4660I: + *device_name = ME4600_NAME_DEVICE_ME4660I; + *device_description = ME4600_DESCRIPTION_DEVICE_ME4660I; + *driver_name = ME4600_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME4660S: + *device_name = ME4600_NAME_DEVICE_ME4660S; + *device_description = ME4600_DESCRIPTION_DEVICE_ME4660S; + *driver_name = ME4600_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME4660IS: + *device_name = ME4600_NAME_DEVICE_ME4660IS; + *device_description = ME4600_DESCRIPTION_DEVICE_ME4660IS; + *driver_name = ME4600_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME4670: + *device_name = ME4600_NAME_DEVICE_ME4670; + *device_description = ME4600_DESCRIPTION_DEVICE_ME4670; + *driver_name = ME4600_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME4670I: + *device_name = ME4600_NAME_DEVICE_ME4670I; + *device_description = ME4600_DESCRIPTION_DEVICE_ME4670I; + *driver_name = ME4600_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME4670S: + *device_name = ME4600_NAME_DEVICE_ME4670S; + *device_description = ME4600_DESCRIPTION_DEVICE_ME4670S; + *driver_name = ME4600_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME4670IS: + *device_name = ME4600_NAME_DEVICE_ME4670IS; + *device_description = ME4600_DESCRIPTION_DEVICE_ME4670IS; + *driver_name = ME4600_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME4680: + *device_name = ME4600_NAME_DEVICE_ME4680; + *device_description = ME4600_DESCRIPTION_DEVICE_ME4680; + *driver_name = ME4600_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME4680I: + *device_name = ME4600_NAME_DEVICE_ME4680I; + *device_description = ME4600_DESCRIPTION_DEVICE_ME4680I; + *driver_name = ME4600_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME4680S: + *device_name = ME4600_NAME_DEVICE_ME4680S; + *device_description = ME4600_DESCRIPTION_DEVICE_ME4680S; + *driver_name = ME4600_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME4680IS: + *device_name = ME4600_NAME_DEVICE_ME4680IS; + *device_description = ME4600_DESCRIPTION_DEVICE_ME4680IS; + *driver_name = ME4600_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME6004: + *device_name = ME6000_NAME_DEVICE_ME60004; + *device_description = ME6000_DESCRIPTION_DEVICE_ME60004; + *driver_name = ME6000_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME6008: + *device_name = ME6000_NAME_DEVICE_ME60008; + *device_description = ME6000_DESCRIPTION_DEVICE_ME60008; + *driver_name = ME6000_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME600F: + *device_name = ME6000_NAME_DEVICE_ME600016; + *device_description = ME6000_DESCRIPTION_DEVICE_ME600016; + *driver_name = ME6000_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME6014: + *device_name = ME6000_NAME_DEVICE_ME6000I4; + *device_description = ME6000_DESCRIPTION_DEVICE_ME6000I4; + *driver_name = ME6000_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME6018: + *device_name = ME6000_NAME_DEVICE_ME6000I8; + *device_description = ME6000_DESCRIPTION_DEVICE_ME6000I8; + *driver_name = ME6000_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME601F: + *device_name = ME6000_NAME_DEVICE_ME6000I16; + *device_description = ME6000_DESCRIPTION_DEVICE_ME6000I16; + *driver_name = ME6000_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME6034: + *device_name = ME6000_NAME_DEVICE_ME6000ISLE4; + *device_description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE4; + *driver_name = ME6000_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME6038: + *device_name = ME6000_NAME_DEVICE_ME6000ISLE8; + *device_description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE8; + *driver_name = ME6000_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME603F: + *device_name = ME6000_NAME_DEVICE_ME6000ISLE16; + *device_description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE16; + *driver_name = ME6000_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME6104: + *device_name = ME6000_NAME_DEVICE_ME61004; + *device_description = ME6000_DESCRIPTION_DEVICE_ME61004; + *driver_name = ME6000_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME6108: + *device_name = ME6000_NAME_DEVICE_ME61008; + *device_description = ME6000_DESCRIPTION_DEVICE_ME61008; + *driver_name = ME6000_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME610F: + *device_name = ME6000_NAME_DEVICE_ME610016; + *device_description = ME6000_DESCRIPTION_DEVICE_ME610016; + *driver_name = ME6000_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME6114: + *device_name = ME6000_NAME_DEVICE_ME6100I4; + *device_description = ME6000_DESCRIPTION_DEVICE_ME6100I4; + *driver_name = ME6000_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME6118: + *device_name = ME6000_NAME_DEVICE_ME6100I8; + *device_description = ME6000_DESCRIPTION_DEVICE_ME6100I8; + *driver_name = ME6000_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME611F: + *device_name = ME6000_NAME_DEVICE_ME6100I16; + *device_description = ME6000_DESCRIPTION_DEVICE_ME6100I16; + *driver_name = ME6000_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME6134: + *device_name = ME6000_NAME_DEVICE_ME6100ISLE4; + *device_description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE4; + *driver_name = ME6000_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME6138: + *device_name = ME6000_NAME_DEVICE_ME6100ISLE8; + *device_description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE8; + *driver_name = ME6000_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME613F: + *device_name = ME6000_NAME_DEVICE_ME6100ISLE16; + *device_description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE16; + *driver_name = ME6000_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME6044: + *device_name = ME6000_NAME_DEVICE_ME60004DIO; + *device_description = ME6000_DESCRIPTION_DEVICE_ME60004DIO; + *driver_name = ME6000_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME6048: + *device_name = ME6000_NAME_DEVICE_ME60008DIO; + *device_description = ME6000_DESCRIPTION_DEVICE_ME60008DIO; + *driver_name = ME6000_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME604F: + *device_name = ME6000_NAME_DEVICE_ME600016DIO; + *device_description = ME6000_DESCRIPTION_DEVICE_ME600016DIO; + *driver_name = ME6000_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME6054: + *device_name = ME6000_NAME_DEVICE_ME6000I4DIO; + *device_description = ME6000_DESCRIPTION_DEVICE_ME6000I4DIO; + *driver_name = ME6000_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME6058: + *device_name = ME6000_NAME_DEVICE_ME6000I8DIO; + *device_description = ME6000_DESCRIPTION_DEVICE_ME6000I8DIO; + *driver_name = ME6000_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME605F: + *device_name = ME6000_NAME_DEVICE_ME6000I16DIO; + *device_description = ME6000_DESCRIPTION_DEVICE_ME6000I16DIO; + *driver_name = ME6000_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME6074: + *device_name = ME6000_NAME_DEVICE_ME6000ISLE4DIO; + *device_description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE4DIO; + *driver_name = ME6000_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME6078: + *device_name = ME6000_NAME_DEVICE_ME6000ISLE8DIO; + *device_description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE8DIO; + *driver_name = ME6000_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME607F: + *device_name = ME6000_NAME_DEVICE_ME6000ISLE16DIO; + *device_description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE16DIO; + *driver_name = ME6000_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME6144: + *device_name = ME6000_NAME_DEVICE_ME61004DIO; + *device_description = ME6000_DESCRIPTION_DEVICE_ME61004DIO; + *driver_name = ME6000_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME6148: + *device_name = ME6000_NAME_DEVICE_ME61008DIO; + *device_description = ME6000_DESCRIPTION_DEVICE_ME61008DIO; + *driver_name = ME6000_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME614F: + *device_name = ME6000_NAME_DEVICE_ME610016DIO; + *device_description = ME6000_DESCRIPTION_DEVICE_ME610016DIO; + *driver_name = ME6000_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME6154: + *device_name = ME6000_NAME_DEVICE_ME6100I4DIO; + *device_description = ME6000_DESCRIPTION_DEVICE_ME6100I4DIO; + *driver_name = ME6000_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME6158: + *device_name = ME6000_NAME_DEVICE_ME6100I8DIO; + *device_description = ME6000_DESCRIPTION_DEVICE_ME6100I8DIO; + *driver_name = ME6000_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME615F: + *device_name = ME6000_NAME_DEVICE_ME6100I16DIO; + *device_description = ME6000_DESCRIPTION_DEVICE_ME6100I16DIO; + *driver_name = ME6000_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME6174: + *device_name = ME6000_NAME_DEVICE_ME6100ISLE4DIO; + *device_description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE4DIO; + *driver_name = ME6000_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME6178: + *device_name = ME6000_NAME_DEVICE_ME6100ISLE8DIO; + *device_description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE8DIO; + *driver_name = ME6000_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME617F: + *device_name = ME6000_NAME_DEVICE_ME6100ISLE16DIO; + *device_description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE16DIO; + *driver_name = ME6000_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME6259: + *device_name = ME6000_NAME_DEVICE_ME6200I9DIO; + *device_description = ME6000_DESCRIPTION_DEVICE_ME6200I9DIO; + *driver_name = ME6000_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME6359: + *device_name = ME6000_NAME_DEVICE_ME6300I9DIO; + *device_description = ME6000_DESCRIPTION_DEVICE_ME6300I9DIO; + *driver_name = ME6000_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME0630: + *device_name = ME0600_NAME_DEVICE_ME0630; + *device_description = ME0600_DESCRIPTION_DEVICE_ME0630; + *driver_name = ME0600_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME8100_A: + *device_name = ME8100_NAME_DEVICE_ME8100A; + *device_description = ME8100_DESCRIPTION_DEVICE_ME8100A; + *driver_name = ME8100_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME8100_B: + *device_name = ME8100_NAME_DEVICE_ME8100B; + *device_description = ME8100_DESCRIPTION_DEVICE_ME8100B; + *driver_name = ME8100_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME8200_A: + *device_name = ME8200_NAME_DEVICE_ME8200A; + *device_description = ME8200_DESCRIPTION_DEVICE_ME8200A; + *driver_name = ME8200_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME8200_B: + *device_name = ME8200_NAME_DEVICE_ME8200B; + *device_description = ME8200_DESCRIPTION_DEVICE_ME8200B; + *driver_name = ME8200_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME0940: + *device_name = ME0900_NAME_DEVICE_ME0940; + *device_description = ME0900_DESCRIPTION_DEVICE_ME0940; + *driver_name = ME0900_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME0950: + *device_name = ME0900_NAME_DEVICE_ME0950; + *device_description = ME0900_DESCRIPTION_DEVICE_ME0950; + *driver_name = ME0900_NAME_DRIVER; + break; + + case PCI_DEVICE_ID_MEILHAUS_ME0960: + *device_name = ME0900_NAME_DEVICE_ME0960; + *device_description = ME0900_DESCRIPTION_DEVICE_ME0960; + *driver_name = ME0900_NAME_DRIVER; + break; +/* + case USB_DEVICE_ID_MEPHISTO_S1: + *device_name = MEPHISTO_S1_NAME_DEVICE; + *device_description = MEPHISTO_S1_DESCRIPTION_DEVICE; + *driver_name = MEPHISTO_S1_NAME_DRIVER; + break; +*/ + default: + *device_name = EMPTY_NAME_DEVICE; + *device_description = EMPTY_DESCRIPTION_DEVICE; + *driver_name = EMPTY_NAME_DRIVER; + + PERROR("Invalid device id.\n"); + + return 1; + } + + return 0; +} + +int me_device_pci_init(me_device_t * me_device, struct pci_dev *pci_device) +{ + int err; + int i; + + PDEBUG("executed.\n"); + + // Initialize device list head. + INIT_LIST_HEAD(&me_device->list); + + // Initialize device description strings. + err = get_device_descriptions(pci_device->device, + &me_device->device_name, + &me_device->device_description, + &me_device->driver_name); + + if (err) { + PERROR("Cannot initialize device description strings.\n"); + return 1; + } + // Enable the pci device. + err = pci_enable_device(pci_device); + + if (err < 0) { + PERROR("Cannot enable PCI device.\n"); + return 1; + } + // Request the PCI register regions. + err = pci_request_regions(pci_device, me_device->device_name); + + if (err < 0) { + PERROR("Cannot request PCI regions.\n"); + goto ERROR_0; + } + // The bus carrying the device is a PCI bus. + me_device->bus_type = ME_BUS_TYPE_PCI; + + // Store the PCI information for later usage. + me_device->info.pci.pci_device = pci_device; + + // Get PCI register bases and sizes. + for (i = 0; i < 6; i++) { + me_device->info.pci.reg_bases[i] = + pci_resource_start(pci_device, i); + me_device->info.pci.reg_sizes[i] = + pci_resource_len(pci_device, i); + } + + // Get the PCI location. + me_device->info.pci.pci_bus_no = pci_device->bus->number; + me_device->info.pci.pci_dev_no = PCI_SLOT(pci_device->devfn); + me_device->info.pci.pci_func_no = PCI_FUNC(pci_device->devfn); + + // Get Meilhaus specific device information. + me_device->info.pci.vendor_id = pci_device->vendor; + me_device->info.pci.device_id = pci_device->device; + pci_read_config_byte(pci_device, 0x08, + &me_device->info.pci.hw_revision); + pci_read_config_dword(pci_device, 0x2C, &me_device->info.pci.serial_no); + + // Get the interrupt request number. + me_device->irq = pci_device->irq; + + // Initialize device lock instance. + err = me_dlock_init(&me_device->dlock); + + if (err) { + PERROR("Cannot initialize device lock instance.\n"); + goto ERROR_1; + } + // Initialize subdevice list instance. + me_slist_init(&me_device->slist); + + if (err) { + PERROR("Cannot initialize subdevice list instance.\n"); + goto ERROR_2; + } + // Initialize method pointers. + me_device->me_device_io_irq_start = me_device_io_irq_start; + me_device->me_device_io_irq_wait = me_device_io_irq_wait; + me_device->me_device_io_irq_stop = me_device_io_irq_stop; + me_device->me_device_io_reset_device = me_device_io_reset_device; + me_device->me_device_io_reset_subdevice = me_device_io_reset_subdevice; + me_device->me_device_io_single_config = me_device_io_single_config; + me_device->me_device_io_single_read = me_device_io_single_read; + me_device->me_device_io_single_write = me_device_io_single_write; + me_device->me_device_io_stream_config = me_device_io_stream_config; + me_device->me_device_io_stream_new_values = + me_device_io_stream_new_values; + me_device->me_device_io_stream_read = me_device_io_stream_read; + me_device->me_device_io_stream_start = me_device_io_stream_start; + me_device->me_device_io_stream_status = me_device_io_stream_status; + me_device->me_device_io_stream_stop = me_device_io_stream_stop; + me_device->me_device_io_stream_write = me_device_io_stream_write; + me_device->me_device_lock_device = me_device_lock_device; + me_device->me_device_lock_subdevice = me_device_lock_subdevice; + me_device->me_device_query_description_device = + me_device_query_description_device; + me_device->me_device_query_info_device = me_device_query_info_device; + me_device->me_device_query_name_device = me_device_query_name_device; + me_device->me_device_query_name_device_driver = + me_device_query_name_device_driver; + me_device->me_device_query_number_subdevices = + me_device_query_number_subdevices; + me_device->me_device_query_number_channels = + me_device_query_number_channels; + me_device->me_device_query_number_ranges = + me_device_query_number_ranges; + me_device->me_device_query_range_by_min_max = + me_device_query_range_by_min_max; + me_device->me_device_query_range_info = me_device_query_range_info; + me_device->me_device_query_subdevice_by_type = + me_device_query_subdevice_by_type; + me_device->me_device_query_subdevice_type = + me_device_query_subdevice_type; + me_device->me_device_query_subdevice_caps = + me_device_query_subdevice_caps; + me_device->me_device_query_subdevice_caps_args = + me_device_query_subdevice_caps_args; + me_device->me_device_query_timer = me_device_query_timer; + me_device->me_device_query_version_device_driver = + me_device_query_version_device_driver; + me_device->me_device_config_load = me_device_config_load; + me_device->me_device_destructor = me_device_destructor; + + return 0; + + ERROR_0: + me_dlock_deinit(&me_device->dlock); + + ERROR_1: + pci_release_regions(pci_device); + + ERROR_2: + pci_disable_device(pci_device); + + return 1; +} + +void me_device_deinit(me_device_t * me_device) +{ + PDEBUG("executed.\n"); + + me_slist_deinit(&me_device->slist); + me_dlock_deinit(&me_device->dlock); + + if (me_device->bus_type == ME_BUS_TYPE_PCI) { + pci_release_regions(me_device->info.pci.pci_device); + pci_disable_device(me_device->info.pci.pci_device); + } +/* + else + { + // Must be an USB device. + } +*/ +} |