diff options
Diffstat (limited to 'drivers/staging/comedi/drivers/adl_pci9118.c')
-rw-r--r-- | drivers/staging/comedi/drivers/adl_pci9118.c | 494 |
1 files changed, 259 insertions, 235 deletions
diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index 06ff65c85c9f..b6dda809bd13 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -62,6 +62,20 @@ Configuration options: 256|=ignore nFull - A/D FIFO Full status */ + +/* + * FIXME + * + * All the supported boards have the same PCI vendor and device IDs, so + * auto-attachment of PCI devices will always find the first board type. + * + * Perhaps the boards have different subdevice IDs that we could use to + * distinguish them? + * + * Need some device attributes so the board type can be corrected after + * attachment if necessary, and possibly to set other options supported by + * manual attachment. + */ #include "../comedidev.h" #include <linux/delay.h> @@ -73,8 +87,6 @@ Configuration options: #include "8253.h" #include "comedi_fc.h" -#define PCI_VENDOR_ID_AMCC 0x10e8 - /* paranoid checks are broken */ #undef PCI9118_PARANOIDCHECK /* * if defined, then is used code which control @@ -210,8 +222,7 @@ static const struct comedi_lrange range_pci9118hg = { 8, { struct boardtype { const char *name; /* board name */ - int vendor_id; /* PCI vendor a device ID of card */ - int device_id; + int device_id; /* PCI device ID of card */ int iorange_amcc; /* iorange for own S5933 region */ int iorange_9118; /* pass thru card region size */ int n_aichan; /* num of A/D chans */ @@ -235,6 +246,61 @@ struct boardtype { }; +static const struct boardtype boardtypes[] = { + { + .name = "pci9118dg", + .device_id = 0x80d9, + .iorange_amcc = AMCC_OP_REG_SIZE, + .iorange_9118 = IORANGE_9118, + .n_aichan = 16, + .n_aichand = 8, + .mux_aichan = 256, + .n_aichanlist = PCI9118_CHANLEN, + .n_aochan = 2, + .ai_maxdata = 0x0fff, + .ao_maxdata = 0x0fff, + .rangelist_ai = &range_pci9118dg_hr, + .rangelist_ao = &range_bipolar10, + .ai_ns_min = 3000, + .ai_pacer_min = 12, + .half_fifo_size = 512, + }, { + .name = "pci9118hg", + .device_id = 0x80d9, + .iorange_amcc = AMCC_OP_REG_SIZE, + .iorange_9118 = IORANGE_9118, + .n_aichan = 16, + .n_aichand = 8, + .mux_aichan = 256, + .n_aichanlist = PCI9118_CHANLEN, + .n_aochan = 2, + .ai_maxdata = 0x0fff, + .ao_maxdata = 0x0fff, + .rangelist_ai = &range_pci9118hg, + .rangelist_ao = &range_bipolar10, + .ai_ns_min = 3000, + .ai_pacer_min = 12, + .half_fifo_size = 512, + }, { + .name = "pci9118hr", + .device_id = 0x80d9, + .iorange_amcc = AMCC_OP_REG_SIZE, + .iorange_9118 = IORANGE_9118, + .n_aichan = 16, + .n_aichand = 8, + .mux_aichan = 256, + .n_aichanlist = PCI9118_CHANLEN, + .n_aochan = 2, + .ai_maxdata = 0xffff, + .ao_maxdata = 0x0fff, + .rangelist_ai = &range_pci9118dg_hr, + .rangelist_ao = &range_bipolar10, + .ai_ns_min = 10000, + .ai_pacer_min = 40, + .half_fifo_size = 512, + }, +}; + struct pci9118_private { unsigned long iobase_a; /* base+size for AMCC chip */ unsigned int master; /* master capable */ @@ -358,10 +424,8 @@ static int check_channel_list(struct comedi_device *dev, return 0; } if ((frontadd + n_chan + backadd) > s->len_chanlist) { - printk - ("comedi%d: range/channel list is too long for " - "actual configuration (%d>%d)!", - dev->minor, n_chan, s->len_chanlist - frontadd - backadd); + comedi_error(dev, + "range/channel list is too long for actual configuration!\n"); return 0; } @@ -892,11 +956,10 @@ static void interrupt_pci9118_ai_onesample(struct comedi_device *dev, if (devpriv->ai16bits == 0) { if ((sampl & 0x000f) != devpriv->chanlist[s->async->cur_chan]) { /* data dropout! */ - printk - ("comedi: A/D SAMPL - data dropout: " - "received channel %d, expected %d!\n", - sampl & 0x000f, - devpriv->chanlist[s->async->cur_chan]); + dev_info(dev->class_dev, + "A/D SAMPL - data dropout: received channel %d, expected %d!\n", + sampl & 0x000f, + devpriv->chanlist[s->async->cur_chan]); s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; pci9118_ai_cancel(dev, s); comedi_event(dev, s); @@ -1153,19 +1216,13 @@ static int pci9118_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ if (cmd->start_src & (TRIG_NOW | TRIG_EXT)) - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); if (cmd->scan_begin_src & (TRIG_FOLLOW | TRIG_EXT)) - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); if ((cmd->scan_begin_src == TRIG_TIMER) && (cmd->convert_src == TRIG_TIMER) && (cmd->scan_end_arg == 1)) { @@ -1175,64 +1232,40 @@ static int pci9118_ai_cmdtest(struct comedi_device *dev, } if (cmd->scan_begin_src == TRIG_TIMER) - if (cmd->scan_begin_arg < this_board->ai_ns_min) { - cmd->scan_begin_arg = this_board->ai_ns_min; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + this_board->ai_ns_min); if (cmd->scan_begin_src == TRIG_EXT) if (cmd->scan_begin_arg) { cmd->scan_begin_arg = 0; - err++; - if (cmd->scan_end_arg > 65535) { - cmd->scan_end_arg = 65535; - err++; - } + err |= -EINVAL; + err |= cfc_check_trigger_arg_max(&cmd->scan_end_arg, + 65535); } if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW)) - if (cmd->convert_arg < this_board->ai_ns_min) { - cmd->convert_arg = this_board->ai_ns_min; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, + this_board->ai_ns_min); if (cmd->convert_src == TRIG_EXT) - if (cmd->convert_arg) { - cmd->convert_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); - if (cmd->stop_src == TRIG_COUNT) { - if (!cmd->stop_arg) { - cmd->stop_arg = 1; - err++; - } - } else { /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + if (cmd->stop_src == TRIG_COUNT) + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); + else /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); - if (!cmd->chanlist_len) { - cmd->chanlist_len = 1; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1); + err |= cfc_check_trigger_arg_max(&cmd->chanlist_len, + this_board->n_aichanlist); - if (cmd->chanlist_len > this_board->n_aichanlist) { - cmd->chanlist_len = this_board->n_aichanlist; - err++; - } - - if (cmd->scan_end_arg < cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->scan_end_arg, + cmd->chanlist_len); if ((cmd->scan_end_arg % cmd->chanlist_len)) { cmd->scan_end_arg = cmd->chanlist_len * (cmd->scan_end_arg / cmd->chanlist_len); - err++; + err |= -EINVAL; } if (err) @@ -1318,21 +1351,18 @@ static int Compute_and_setup_dma(struct comedi_device *dev) if (dmalen0 < (devpriv->ai_n_realscanlen << 1)) { /* uff, too short DMA buffer, disable EOS support! */ devpriv->ai_flags &= (~TRIG_WAKE_EOS); - printk - ("comedi%d: WAR: DMA0 buf too short, can't " - "support TRIG_WAKE_EOS (%d<%d)\n", - dev->minor, dmalen0, - devpriv->ai_n_realscanlen << 1); + dev_info(dev->class_dev, + "WAR: DMA0 buf too short, can't support TRIG_WAKE_EOS (%d<%d)\n", + dmalen0, devpriv->ai_n_realscanlen << 1); } else { /* short first DMA buffer to one scan */ dmalen0 = devpriv->ai_n_realscanlen << 1; if (devpriv->useeoshandle) dmalen0 += 2; if (dmalen0 < 4) { - printk - ("comedi%d: ERR: DMA0 buf len bug? " - "(%d<4)\n", - dev->minor, dmalen0); + dev_info(dev->class_dev, + "ERR: DMA0 buf len bug? (%d<4)\n", + dmalen0); dmalen0 = 4; } } @@ -1341,21 +1371,18 @@ static int Compute_and_setup_dma(struct comedi_device *dev) if (dmalen1 < (devpriv->ai_n_realscanlen << 1)) { /* uff, too short DMA buffer, disable EOS support! */ devpriv->ai_flags &= (~TRIG_WAKE_EOS); - printk - ("comedi%d: WAR: DMA1 buf too short, " - "can't support TRIG_WAKE_EOS (%d<%d)\n", - dev->minor, dmalen1, - devpriv->ai_n_realscanlen << 1); + dev_info(dev->class_dev, + "WAR: DMA1 buf too short, can't support TRIG_WAKE_EOS (%d<%d)\n", + dmalen1, devpriv->ai_n_realscanlen << 1); } else { /* short second DMA buffer to one scan */ dmalen1 = devpriv->ai_n_realscanlen << 1; if (devpriv->useeoshandle) dmalen1 -= 2; if (dmalen1 < 4) { - printk - ("comedi%d: ERR: DMA1 buf len bug? " - "(%d<4)\n", - dev->minor, dmalen1); + dev_info(dev->class_dev, + "ERR: DMA1 buf len bug? (%d<4)\n", + dmalen1); dmalen1 = 4; } } @@ -1865,6 +1892,20 @@ static int pci9118_reset(struct comedi_device *dev) return 0; } +/* + * FIXME - this is pretty ineffective because all the supported board types + * have the same device ID! + */ +static const struct boardtype *pci9118_find_boardinfo(struct pci_dev *pcidev) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(boardtypes); i++) + if (pcidev->device == boardtypes[i].device_id) + return &boardtypes[i]; + return NULL; +} + static struct pci_dev *pci9118_find_pci(struct comedi_device *dev, struct comedi_devconfig *it) { @@ -1884,85 +1925,63 @@ static struct pci_dev *pci9118_find_pci(struct comedi_device *dev, PCI_SLOT(pcidev->devfn) != slot) continue; } - /* - * Look for device that isn't in use. - * Enable PCI device and request regions. - */ - if (comedi_pci_enable(pcidev, "adl_pci9118")) - continue; - printk(KERN_ERR ", b:s:f=%d:%d:%d, io=0x%4lx, 0x%4lx", - pcidev->bus->number, - PCI_SLOT(pcidev->devfn), - PCI_FUNC(pcidev->devfn), - (unsigned long)pci_resource_start(pcidev, 2), - (unsigned long)pci_resource_start(pcidev, 0)); return pcidev; } - printk(KERN_ERR - "comedi%d: no supported board found! (req. bus/slot : %d/%d)\n", - dev->minor, bus, slot); + dev_err(dev->class_dev, + "no supported board found! (req. bus/slot : %d/%d)\n", + bus, slot); return NULL; } -static int pci9118_attach(struct comedi_device *dev, - struct comedi_devconfig *it) +static void pci9118_report_attach(struct comedi_device *dev, unsigned int irq) +{ + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct pci9118_private *devpriv = dev->private; + char irqbuf[30]; + char muxbuf[30]; + + if (irq) + snprintf(irqbuf, sizeof(irqbuf), "irq %u%s", irq, + (dev->irq ? "" : " UNAVAILABLE")); + else + snprintf(irqbuf, sizeof(irqbuf), "irq DISABLED"); + if (devpriv->usemux) + snprintf(muxbuf, sizeof(muxbuf), "ext mux %u chans", + devpriv->usemux); + else + snprintf(muxbuf, sizeof(muxbuf), "no ext mux"); + dev_info(dev->class_dev, "%s (pci %s, %s, %sbus master, %s) attached\n", + dev->board_name, pci_name(pcidev), irqbuf, + (devpriv->master ? "" : "no "), muxbuf); +} + +static int pci9118_common_attach(struct comedi_device *dev, int disable_irq, + int master, int ext_mux, int softsshdelay, + int hw_err_mask) { const struct boardtype *this_board = comedi_board(dev); - struct pci9118_private *devpriv; - struct pci_dev *pcidev; + struct pci9118_private *devpriv = dev->private; + struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct comedi_subdevice *s; int ret, pages, i; - unsigned short master; unsigned int irq; u16 u16w; - printk("comedi%d: adl_pci9118: board=%s", dev->minor, this_board->name); - - if (it->options[3] & 1) - master = 0; /* user don't want use bus master */ - else - master = 1; - - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret < 0) { - printk(" - Allocation failed!\n"); - return -ENOMEM; + dev->board_name = this_board->name; + ret = comedi_pci_enable(pcidev, dev->board_name); + if (ret) { + dev_err(dev->class_dev, + "cannot enable PCI device %s\n", pci_name(pcidev)); + return ret; } - devpriv = dev->private; - - pcidev = pci9118_find_pci(dev, it); - if (!pcidev) - return -EIO; - comedi_set_hw_dev(dev, &pcidev->dev); - if (master) pci_set_master(pcidev); - irq = pcidev->irq; devpriv->iobase_a = pci_resource_start(pcidev, 0); dev->iobase = pci_resource_start(pcidev, 2); - dev->board_name = this_board->name; - pci9118_reset(dev); - if (it->options[3] & 2) - irq = 0; /* user don't want use IRQ */ - if (irq > 0) { - if (request_irq(irq, interrupt_pci9118, IRQF_SHARED, - "ADLink PCI-9118", dev)) { - printk(", unable to allocate IRQ %d, DISABLING IT", - irq); - irq = 0; /* Can't use IRQ */ - } else { - printk(", irq=%u", irq); - } - } else { - printk(", IRQ disabled"); - } - - dev->irq = irq; - if (master) { /* alloc DMA buffers */ devpriv->dma_doublebuf = 0; for (i = 0; i < 2; i++) { @@ -1984,47 +2003,37 @@ static int pci9118_attach(struct comedi_device *dev, } } if (!devpriv->dmabuf_virt[0]) { - printk(", Can't allocate DMA buffer, DMA disabled!"); + dev_warn(dev->class_dev, + "Can't allocate DMA buffer, DMA disabled!\n"); master = 0; } - if (devpriv->dmabuf_virt[1]) devpriv->dma_doublebuf = 1; - } - devpriv->master = master; - if (devpriv->master) - printk(", bus master"); - else - printk(", no bus master"); - - devpriv->usemux = 0; - if (it->options[2] > 0) { - devpriv->usemux = it->options[2]; - if (devpriv->usemux > 256) - devpriv->usemux = 256; /* max 256 channels! */ - if (it->options[4] > 0) - if (devpriv->usemux > 128) { - devpriv->usemux = 128; - /* max 128 channels with softare S&H! */ - } - printk(", ext. mux %d channels", devpriv->usemux); + + if (ext_mux > 0) { + if (ext_mux > 256) + ext_mux = 256; /* max 256 channels! */ + if (softsshdelay > 0) + if (ext_mux > 128) + ext_mux = 128; + devpriv->usemux = ext_mux; + } else { + devpriv->usemux = 0; } - devpriv->softsshdelay = it->options[4]; - if (devpriv->softsshdelay < 0) { - /* select sample&hold signal polarity */ - devpriv->softsshdelay = -devpriv->softsshdelay; + if (softsshdelay < 0) { + /* select sample&hold signal polarity */ + devpriv->softsshdelay = -softsshdelay; devpriv->softsshsample = 0x80; devpriv->softsshhold = 0x00; } else { + devpriv->softsshdelay = softsshdelay; devpriv->softsshsample = 0x00; devpriv->softsshhold = 0x80; } - printk(".\n"); - pci_read_config_word(pcidev, PCI_COMMAND, &u16w); pci_write_config_word(pcidev, PCI_COMMAND, u16w | 64); /* Enable parity check for parity error */ @@ -2047,12 +2056,7 @@ static int pci9118_attach(struct comedi_device *dev, s->range_table = this_board->rangelist_ai; s->cancel = pci9118_ai_cancel; s->insn_read = pci9118_insn_read_ai; - if (dev->irq) { - s->subdev_flags |= SDF_CMD_READ; - s->do_cmdtest = pci9118_ai_cmdtest; - s->do_cmd = pci9118_ai_cmd; - s->munge = pci9118_ai_munge; - } + s->munge = pci9118_ai_munge; s = &dev->subdevices[1]; s->type = COMEDI_SUBD_AO; @@ -2088,8 +2092,8 @@ static int pci9118_attach(struct comedi_device *dev, devpriv->i8254_osc_base = 250; /* 250ns=4MHz */ devpriv->ai_maskharderr = 0x10a; /* default measure crash condition */ - if (it->options[5]) /* disable some requested */ - devpriv->ai_maskharderr &= ~it->options[5]; + if (hw_err_mask) /* disable some requested */ + devpriv->ai_maskharderr &= ~hw_err_mask; switch (this_board->ai_maxdata) { case 0xffff: @@ -2099,9 +2103,86 @@ static int pci9118_attach(struct comedi_device *dev, devpriv->ai16bits = 0; break; } + + if (disable_irq) + irq = 0; + else + irq = pcidev->irq; + if (irq > 0) { + if (request_irq(irq, interrupt_pci9118, IRQF_SHARED, + dev->board_name, dev)) { + dev_warn(dev->class_dev, + "unable to allocate IRQ %u, DISABLING IT\n", + irq); + } else { + dev->irq = irq; + /* Enable AI commands */ + s = &dev->subdevices[0]; + s->subdev_flags |= SDF_CMD_READ; + s->do_cmdtest = pci9118_ai_cmdtest; + s->do_cmd = pci9118_ai_cmd; + } + } + + pci9118_report_attach(dev, irq); return 0; } +static int pci9118_attach(struct comedi_device *dev, + struct comedi_devconfig *it) +{ + struct pci9118_private *devpriv; + struct pci_dev *pcidev; + int ext_mux, disable_irq, master, softsshdelay, hw_err_mask; + + ext_mux = it->options[2]; + master = ((it->options[3] & 1) == 0); + disable_irq = ((it->options[3] & 2) != 0); + softsshdelay = it->options[4]; + hw_err_mask = it->options[5]; + + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; + + pcidev = pci9118_find_pci(dev, it); + if (!pcidev) + return -EIO; + comedi_set_hw_dev(dev, &pcidev->dev); + + return pci9118_common_attach(dev, disable_irq, master, ext_mux, + softsshdelay, hw_err_mask); +} + +static int pci9118_auto_attach(struct comedi_device *dev, + unsigned long context_unused) +{ + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct pci9118_private *devpriv; + + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; + + dev->board_ptr = pci9118_find_boardinfo(pcidev); + if (dev->board_ptr == NULL) { + dev_err(dev->class_dev, + "adl_pci9118: cannot determine board type for pci %s\n", + pci_name(pcidev)); + return -EINVAL; + } + /* + * Need to 'get' the PCI device to match the 'put' in pci9118_detach(). + * (The 'put' also matches the implicit 'get' by pci9118_find_pci().) + */ + pci_dev_get(pcidev); + /* Don't disable irq, use bus master, no external mux, + * no sample-hold delay, no error mask. */ + return pci9118_common_attach(dev, 0, 1, 0, 0, 0); +} + static void pci9118_detach(struct comedi_device *dev) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -2127,81 +2208,24 @@ static void pci9118_detach(struct comedi_device *dev) } } -static const struct boardtype boardtypes[] = { - { - .name = "pci9118dg", - .vendor_id = PCI_VENDOR_ID_AMCC, - .device_id = 0x80d9, - .iorange_amcc = AMCC_OP_REG_SIZE, - .iorange_9118 = IORANGE_9118, - .n_aichan = 16, - .n_aichand = 8, - .mux_aichan = 256, - .n_aichanlist = PCI9118_CHANLEN, - .n_aochan = 2, - .ai_maxdata = 0x0fff, - .ao_maxdata = 0x0fff, - .rangelist_ai = &range_pci9118dg_hr, - .rangelist_ao = &range_bipolar10, - .ai_ns_min = 3000, - .ai_pacer_min = 12, - .half_fifo_size = 512, - }, { - .name = "pci9118hg", - .vendor_id = PCI_VENDOR_ID_AMCC, - .device_id = 0x80d9, - .iorange_amcc = AMCC_OP_REG_SIZE, - .iorange_9118 = IORANGE_9118, - .n_aichan = 16, - .n_aichand = 8, - .mux_aichan = 256, - .n_aichanlist = PCI9118_CHANLEN, - .n_aochan = 2, - .ai_maxdata = 0x0fff, - .ao_maxdata = 0x0fff, - .rangelist_ai = &range_pci9118hg, - .rangelist_ao = &range_bipolar10, - .ai_ns_min = 3000, - .ai_pacer_min = 12, - .half_fifo_size = 512, - }, { - .name = "pci9118hr", - .vendor_id = PCI_VENDOR_ID_AMCC, - .device_id = 0x80d9, - .iorange_amcc = AMCC_OP_REG_SIZE, - .iorange_9118 = IORANGE_9118, - .n_aichan = 16, - .n_aichand = 8, - .mux_aichan = 256, - .n_aichanlist = PCI9118_CHANLEN, - .n_aochan = 2, - .ai_maxdata = 0xffff, - .ao_maxdata = 0x0fff, - .rangelist_ai = &range_pci9118dg_hr, - .rangelist_ao = &range_bipolar10, - .ai_ns_min = 10000, - .ai_pacer_min = 40, - .half_fifo_size = 512, - }, -}; - static struct comedi_driver adl_pci9118_driver = { .driver_name = "adl_pci9118", .module = THIS_MODULE, .attach = pci9118_attach, + .auto_attach = pci9118_auto_attach, .detach = pci9118_detach, .num_names = ARRAY_SIZE(boardtypes), .board_name = &boardtypes[0].name, .offset = sizeof(struct boardtype), }; -static int __devinit adl_pci9118_pci_probe(struct pci_dev *dev, +static int adl_pci9118_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &adl_pci9118_driver); } -static void __devexit adl_pci9118_pci_remove(struct pci_dev *dev) +static void adl_pci9118_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } @@ -2216,7 +2240,7 @@ static struct pci_driver adl_pci9118_pci_driver = { .name = "adl_pci9118", .id_table = adl_pci9118_pci_table, .probe = adl_pci9118_pci_probe, - .remove = __devexit_p(adl_pci9118_pci_remove), + .remove = adl_pci9118_pci_remove, }; module_comedi_pci_driver(adl_pci9118_driver, adl_pci9118_pci_driver); |