aboutsummaryrefslogtreecommitdiff
path: root/drivers/staging/comedi/drivers/skel.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/comedi/drivers/skel.c')
-rw-r--r--drivers/staging/comedi/drivers/skel.c136
1 files changed, 65 insertions, 71 deletions
diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c
index cb83f6ae48b..dbc8c54d6da 100644
--- a/drivers/staging/comedi/drivers/skel.c
+++ b/drivers/staging/comedi/drivers/skel.c
@@ -90,29 +90,30 @@ Configuration Options:
* boards in this way is optional, and completely driver-dependent.
* Some drivers use arrays such as this, other do not.
*/
+enum skel_boardid {
+ BOARD_SKEL100,
+ BOARD_SKEL200,
+};
+
struct skel_board {
const char *name;
- unsigned int devid;
int ai_chans;
int ai_bits;
int have_dio;
};
static const struct skel_board skel_boards[] = {
- {
- .name = "skel-100",
- .devid = 0x100,
- .ai_chans = 16,
- .ai_bits = 12,
- .have_dio = 1,
- },
- {
- .name = "skel-200",
- .devid = 0x200,
- .ai_chans = 8,
- .ai_bits = 16,
- .have_dio = 0,
- },
+ [BOARD_SKEL100] = {
+ .name = "skel-100",
+ .ai_chans = 16,
+ .ai_bits = 12,
+ .have_dio = 1,
+ },
+ [BOARD_SKEL200] = {
+ .name = "skel-200",
+ .ai_chans = 8,
+ .ai_bits = 16,
+ },
};
/* this structure is for data unique to this hardware driver. If
@@ -394,22 +395,6 @@ static int skel_dio_insn_config(struct comedi_device *dev,
return insn->n;
}
-static const struct skel_board *skel_find_pci_board(struct pci_dev *pcidev)
-{
- unsigned int i;
-
-/*
- * This example code assumes all the entries in skel_boards[] are PCI boards
- * and all use the same PCI vendor ID. If skel_boards[] contains a mixture
- * of PCI and non-PCI boards, this loop should skip over the non-PCI boards.
- */
- for (i = 0; i < ARRAY_SIZE(skel_boards); i++)
- if (/* skel_boards[i].bustype == pci_bustype && */
- pcidev->device == skel_boards[i].devid)
- return &skel_boards[i];
- return NULL;
-}
-
/*
* Handle common part of skel_attach() and skel_auto_attach().
*/
@@ -496,10 +481,12 @@ static int skel_attach(struct comedi_device *dev, struct comedi_devconfig *it)
thisboard = comedi_board(dev);
-/*
- * Initialize dev->board_name.
- */
- dev->board_name = thisboard->name;
+ /*
+ * The dev->board_name is initialized by the comedi core before
+ * calling the (*attach) function. It can be optionally set by
+ * the driver if additional probing has been done.
+ */
+ /* dev->board_name = thisboard->name; */
/* Allocate the private data */
devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
@@ -541,16 +528,13 @@ static int skel_attach(struct comedi_device *dev, struct comedi_devconfig *it)
* comedi_usb_auto_config(), etc.) to handle devices that can be attached
* to the Comedi core automatically without the COMEDI_DEVCONFIG ioctl.
*
- * The context parameter is usually unused, but if the driver called
- * comedi_auto_config() directly instead of the comedi_pci_auto_config()
- * wrapper function, this will be a copy of the context passed to
- * comedi_auto_config().
+ * The context parameter is driver dependent.
*/
static int skel_auto_attach(struct comedi_device *dev,
- unsigned long context)
+ unsigned long context)
{
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct skel_board *thisboard;
+ const struct skel_board *thisboard = NULL;
struct skel_private *devpriv;
int ret;
@@ -558,12 +542,18 @@ static int skel_auto_attach(struct comedi_device *dev,
if (!IS_ENABLED(CONFIG_COMEDI_PCI_DRIVERS))
return -EINVAL;
- /* Find a matching board in skel_boards[]. */
- thisboard = skel_find_pci_board(pcidev);
- if (!thisboard) {
- dev_err(dev->class_dev, "BUG! cannot determine board type!\n");
- return -EINVAL;
- }
+ /*
+ * In this example, the _auto_attach is for a PCI device.
+ *
+ * The 'context' passed to this function is the id->driver_data
+ * associated with the PCI device found in the id_table during
+ * the modprobe. This 'context' is the index of the entry in
+ * skel_boards[i] that contains the boardinfo for the PCI device.
+ */
+ if (context < ARRAY_SIZE(skel_boards))
+ thisboard = &skel_boards[context];
+ if (!thisboard)
+ return -ENODEV;
/*
* Point the struct comedi_device to the matching board info
@@ -579,7 +569,7 @@ static int skel_auto_attach(struct comedi_device *dev,
dev->private = devpriv;
/* Enable the PCI device. */
- ret = comedi_pci_enable(pcidev, dev->board_name);
+ ret = comedi_pci_enable(dev);
if (ret)
return ret;
@@ -618,7 +608,6 @@ static void skel_detach(struct comedi_device *dev)
{
const struct skel_board *thisboard = comedi_board(dev);
struct skel_private *devpriv = dev->private;
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
if (!thisboard || !devpriv)
return;
@@ -638,17 +627,17 @@ static void skel_detach(struct comedi_device *dev)
* If PCI device enabled by _auto_attach() (or _attach()),
* disable it here.
*/
- if (pcidev && dev->iobase)
- comedi_pci_disable(pcidev);
+ comedi_pci_disable(dev);
} else {
/*
* ISA board
*
- * If I/O regions successfully requested by _attach(),
- * release them here.
+ * Release the first I/O region requested during the
+ * _attach(). This is safe to call even if the request
+ * failed. If any additional I/O regions are requested
+ * they need to be released by the driver.
*/
- if (dev->iobase)
- release_region(dev->iobase, SKEL_SIZE);
+ comedi_legacy_detach(dev);
}
}
@@ -689,28 +678,33 @@ static struct comedi_driver skel_driver = {
#ifdef CONFIG_COMEDI_PCI_DRIVERS
-/* This is used by modprobe to translate PCI IDs to drivers. Should
- * only be used for PCI and ISA-PnP devices */
-/* Please add your PCI vendor ID to comedidev.h, and it will be forwarded
- * upstream. */
-#define PCI_VENDOR_ID_SKEL 0xdafe
+static int skel_pci_probe(struct pci_dev *dev,
+ const struct pci_device_id *id)
+{
+ return comedi_pci_auto_config(dev, &skel_driver, id->driver_data);
+}
+
+/*
+ * Please add your PCI vendor ID to comedidev.h, and it will
+ * be forwarded upstream.
+ */
+#define PCI_VENDOR_ID_SKEL 0xdafe
+
+/*
+ * This is used by modprobe to translate PCI IDs to drivers.
+ * Should only be used for PCI and ISA-PnP devices
+ */
static DEFINE_PCI_DEVICE_TABLE(skel_pci_table) = {
- { PCI_DEVICE(PCI_VENDOR_ID_SKEL, 0x0100) },
- { PCI_DEVICE(PCI_VENDOR_ID_SKEL, 0x0200) },
+ { PCI_VDEVICE(SKEL, 0x0100), BOARD_SKEL100 },
+ { PCI_VDEVICE(SKEL, 0x0200), BOARD_SKEL200 },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, skel_pci_table);
-static int skel_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
-{
- return comedi_pci_auto_config(dev, &skel_driver);
-}
-
static struct pci_driver skel_pci_driver = {
- .name = "dummy",
- .id_table = skel_pci_table,
- .probe = &skel_pci_probe,
+ .name = "dummy",
+ .id_table = skel_pci_table,
+ .probe = skel_pci_probe,
.remove = comedi_pci_auto_unconfig,
};
module_comedi_pci_driver(skel_driver, skel_pci_driver);