staging: comedi: adl_pci9118: split pci9118_attach()
Split most of the functionality of the attach routine `pci9118_attach()` into a new function `pci9118_common_attach()` that can be called when auto-attachment of devices is supported. Move the enabling of the PCI device and its i/o regions into this function. Do the requesting of the interrupt near the end of the function so it doesn't get enabled before the device is ready. Note that auto-attachment of PCI devices is currently broken in this driver because the list of board names referred to by the `struct comedi_driver` does not contain a "wildcard" entry matching the comedi driver name. This won't be a problem once support for the `auto_attach()` method is added. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
f41d2573b2
commit
f3b81d5458
|
@ -1873,12 +1873,6 @@ 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;
|
||||
return pcidev;
|
||||
}
|
||||
dev_err(dev->class_dev,
|
||||
|
@ -1909,56 +1903,33 @@ static void pci9118_report_attach(struct comedi_device *dev, unsigned int irq)
|
|||
(devpriv->master ? "" : "no "), muxbuf);
|
||||
}
|
||||
|
||||
static int pci9118_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it)
|
||||
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;
|
||||
|
||||
if (it->options[3] & 1)
|
||||
master = 0; /* user don't want use bus master */
|
||||
else
|
||||
master = 1;
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
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))
|
||||
dev_warn(dev->class_dev,
|
||||
"unable to allocate IRQ %u, DISABLING IT\n",
|
||||
irq);
|
||||
else
|
||||
dev->irq = irq;
|
||||
}
|
||||
|
||||
if (master) { /* alloc DMA buffers */
|
||||
devpriv->dma_doublebuf = 0;
|
||||
for (i = 0; i < 2; i++) {
|
||||
|
@ -1984,32 +1955,29 @@ static int pci9118_attach(struct comedi_device *dev,
|
|||
"Can't allocate DMA buffer, DMA disabled!\n");
|
||||
master = 0;
|
||||
}
|
||||
|
||||
if (devpriv->dmabuf_virt[1])
|
||||
devpriv->dma_doublebuf = 1;
|
||||
|
||||
}
|
||||
|
||||
devpriv->master = 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! */
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -2036,12 +2004,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;
|
||||
|
@ -2077,8 +2040,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:
|
||||
|
@ -2088,10 +2051,58 @@ 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 void pci9118_detach(struct comedi_device *dev)
|
||||
{
|
||||
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
|
||||
|
|
Loading…
Reference in New Issue