- plx_regbase_tmp &= PCI_BASE_ADDRESS_MEM_MASK;
- dev_private->plx_regbase_size = plx_regbase_size_tmp;
- dev_private->plx_regbase = (unsigned int) ioremap(plx_regbase_tmp, plx_regbase_size_tmp);
-
- // Read Meilhaus register base address [PCI_BASE_ADDRESS #2].
-
- me_regbase_tmp = pci_resource_start(pci_device, 2);
- me_regbase_size_tmp = pci_resource_end(pci_device, 2) - me_regbase_tmp + 1;
-
- if(me_regbase_tmp & PCI_BASE_ADDRESS_SPACE)
- {
- printk("comedi%d: Meilhaus space is not MEM\n", dev->minor);
- return -EIO;
- }
-
- me_regbase_tmp &= PCI_BASE_ADDRESS_MEM_MASK;
- dev_private->me_regbase_size = me_regbase_size_tmp;
- dev_private->me_regbase = (unsigned int) ioremap(me_regbase_tmp, me_regbase_size_tmp);
-
- // Download firmware and reset card
- if(board->device_id == ME2600_DEVICE_ID)
- {
- me2600_xilinx_download(dev);
- }
-
- me_reset(dev);
-
- // device driver capabilities
-
- dev->n_subdevices = 3;
- if((error = alloc_subdevices(dev)) < 0)
- return error;
-
- subdevice = dev->subdevices + 0;
- subdevice->type = COMEDI_SUBD_AI;
- subdevice->subdev_flags = SDF_READABLE | SDF_COMMON;
- subdevice->n_chan = board->ai_channel_nbr;
- subdevice->maxdata = board->ai_resolution_mask;
- subdevice->len_chanlist = board->ai_channel_nbr;
- subdevice->range_table = board->ai_range_list;
- subdevice->cancel = me_ai_cancel;
- subdevice->insn_read = me_ai_insn_read;
- subdevice->do_cmdtest = me_ai_do_cmd_test;
- subdevice->do_cmd = me_ai_do_cmd;
-
- subdevice = dev->subdevices + 1;
- subdevice->type = COMEDI_SUBD_AO;
- subdevice->subdev_flags = SDF_WRITEABLE | SDF_COMMON;
- subdevice->n_chan = board->ao_channel_nbr;
- subdevice->maxdata = board->ao_resolution_mask;
- subdevice->len_chanlist = board->ao_channel_nbr;
- subdevice->range_table = board->ao_range_list;
- subdevice->insn_read = me_ao_insn_read;
- subdevice->insn_write = me_ao_insn_write;
-
- subdevice = dev->subdevices + 2;
- subdevice->type = COMEDI_SUBD_DIO;
- subdevice->subdev_flags = SDF_READABLE | SDF_WRITEABLE;
- subdevice->n_chan = board->dio_channel_nbr;
- subdevice->maxdata = 1;
- subdevice->len_chanlist = board->dio_channel_nbr;
- subdevice->range_table = &range_digital;
- subdevice->insn_bits = me_dio_insn_bits;
- subdevice->insn_config = me_dio_insn_config;
- subdevice->io_bits = 0;
-
- printk("comedi%d: " ME_DRIVER_NAME " attached.\n", dev->minor);
- return 0;
+ // Read Meilhaus register base address [PCI_BASE_ADDRESS #2].
+
+ me_regbase_tmp = pci_resource_start(pci_device, 2);
+ me_regbase_size_tmp = pci_resource_len(pci_device, 2);
+ dev_private->me_regbase_size = me_regbase_size_tmp;
+ dev_private->me_regbase = ioremap(me_regbase_tmp, me_regbase_size_tmp);
+ if (!dev_private->me_regbase) {
+ printk("comedi%d: Failed to remap I/O memory\n", dev->minor);
+ return -ENOMEM;
+ }
+ // Download firmware and reset card
+ if (board->device_id == ME2600_DEVICE_ID) {
+ unsigned char *aux_data;
+ int aux_len;
+
+ aux_data = comedi_aux_data(it->options, 0);
+ aux_len = it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH];
+
+ if (!aux_data || aux_len < 1) {
+ comedi_error(dev,
+ "You must provide me2600 firmware using the --init-data option of comedi_config");
+ return -EINVAL;
+ }
+ me2600_xilinx_download(dev, aux_data, aux_len);
+ }
+
+ me_reset(dev);
+
+ // device driver capabilities
+
+ if ((error = alloc_subdevices(dev, 3)) < 0)
+ return error;
+
+ subdevice = dev->subdevices + 0;
+ subdevice->type = COMEDI_SUBD_AI;
+ subdevice->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_CMD_READ;
+ subdevice->n_chan = board->ai_channel_nbr;
+ subdevice->maxdata = board->ai_resolution_mask;
+ subdevice->len_chanlist = board->ai_channel_nbr;
+ subdevice->range_table = board->ai_range_list;
+ subdevice->cancel = me_ai_cancel;
+ subdevice->insn_read = me_ai_insn_read;
+ subdevice->do_cmdtest = me_ai_do_cmd_test;
+ subdevice->do_cmd = me_ai_do_cmd;
+
+ subdevice = dev->subdevices + 1;
+ subdevice->type = COMEDI_SUBD_AO;
+ subdevice->subdev_flags = SDF_WRITEABLE | SDF_COMMON;
+ subdevice->n_chan = board->ao_channel_nbr;
+ subdevice->maxdata = board->ao_resolution_mask;
+ subdevice->len_chanlist = board->ao_channel_nbr;
+ subdevice->range_table = board->ao_range_list;
+ subdevice->insn_read = me_ao_insn_read;
+ subdevice->insn_write = me_ao_insn_write;
+
+ subdevice = dev->subdevices + 2;
+ subdevice->type = COMEDI_SUBD_DIO;
+ subdevice->subdev_flags = SDF_READABLE | SDF_WRITEABLE;
+ subdevice->n_chan = board->dio_channel_nbr;
+ subdevice->maxdata = 1;
+ subdevice->len_chanlist = board->dio_channel_nbr;
+ subdevice->range_table = &range_digital;
+ subdevice->insn_bits = me_dio_insn_bits;
+ subdevice->insn_config = me_dio_insn_config;
+ subdevice->io_bits = 0;
+
+ printk("comedi%d: " ME_DRIVER_NAME " attached.\n", dev->minor);
+ return 0;