Support autoconfiguration of PCI devices in some Amplicon drivers.
authorIan Abbott <abbotti@mev.co.uk>
Wed, 22 Oct 2008 14:01:40 +0000 (14:01 +0000)
committerIan Abbott <abbotti@mev.co.uk>
Wed, 22 Oct 2008 14:01:40 +0000 (14:01 +0000)
comedi/drivers/amplc_dio200.c
comedi/drivers/amplc_pc236.c
comedi/drivers/amplc_pc263.c
comedi/drivers/amplc_pci224.c

index fe2ee77a8e0ea009f9680c2bc98ba1dde2a9a11f..228291a569d8ba5604ac74b220c25425af5ec090 100644 (file)
@@ -29,8 +29,9 @@ Driver: amplc_dio200
 Description: Amplicon 200 Series Digital I/O
 Author: Ian Abbott <abbotti@mev.co.uk>
 Devices: [Amplicon] PC212E (pc212e), PC214E (pc214e), PC215E (pc215e),
-  PCI215 (pci215), PC218E (pc218e), PC272E (pc272e), PCI272 (pci272)
-Updated: Mon, 05 Nov 2007 14:04:04 +0000
+  PCI215 (pci215 or amplc_dio200), PC218E (pc218e), PC272E (pc272e),
+  PCI272 (pci272 or amplc_dio200)
+Updated: Wed, 22 Oct 2008 13:36:02 +0100
 Status: works
 
 Configuration options - PC212E, PC214E, PC215E, PC218E, PC272E:
@@ -217,6 +218,7 @@ order they appear in the channel list.
 /* #define PCI_VENDOR_ID_AMPLICON 0x14dc */
 #define PCI_DEVICE_ID_AMPLICON_PCI272 0x000a
 #define PCI_DEVICE_ID_AMPLICON_PCI215 0x000b
+#define PCI_DEVICE_ID_INVALID 0xffff
 
 /* 200 series registers */
 #define DIO200_IO_SIZE         0x20
@@ -264,7 +266,8 @@ enum dio200_model {
        pc214e_model,
        pc215e_model, pci215_model,
        pc218e_model,
-       pc272e_model, pci272_model
+       pc272e_model, pci272_model,
+       anypci_model
 };
 
 enum dio200_layout {
@@ -277,6 +280,7 @@ enum dio200_layout {
 
 typedef struct dio200_board_struct {
        const char *name;
+       unsigned short devid;
        enum dio200_bustype bustype;
        enum dio200_model model;
        enum dio200_layout layout;
@@ -304,6 +308,7 @@ static const dio200_board dio200_boards[] = {
 #ifdef CONFIG_COMEDI_PCI
        {
              name:     "pci215",
+             devid:    PCI_DEVICE_ID_AMPLICON_PCI215,
              bustype:  pci_bustype,
              model:    pci215_model,
              layout:   pc215_layout,
@@ -324,11 +329,20 @@ static const dio200_board dio200_boards[] = {
 #ifdef CONFIG_COMEDI_PCI
        {
              name:     "pci272",
+             devid:    PCI_DEVICE_ID_AMPLICON_PCI272,
              bustype:  pci_bustype,
              model:    pci272_model,
              layout:   pc272_layout,
                },
 #endif
+#ifdef CONFIG_COMEDI_PCI
+       {
+             name:     DIO200_DRIVER_NAME,
+             devid:    PCI_DEVICE_ID_INVALID,
+             bustype:  pci_bustype,
+             model:    anypci_model,   /* wildcard */
+               },
+#endif
 };
 
 /*
@@ -405,9 +419,9 @@ static const dio200_layout dio200_layouts[] = {
 #ifdef CONFIG_COMEDI_PCI
 static DEFINE_PCI_DEVICE_TABLE(dio200_pci_table) = {
        {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI215,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0, pci215_model},
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
        {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI272,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0, pci272_model},
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
        {0}
 };
 
@@ -471,7 +485,11 @@ static comedi_driver driver_amplc_dio200 = {
       num_names:sizeof(dio200_boards) / sizeof(dio200_board),
 };
 
+#ifdef CONFIG_COMEDI_PCI
 COMEDI_PCI_INITCLEANUP(driver_amplc_dio200, dio200_pci_table);
+#else
+COMEDI_INITCLEANUP(driver_amplc_dio200);
+#endif
 
 /*
  * This function looks for a PCI device matching the requested board name,
@@ -483,46 +501,40 @@ dio200_find_pci(comedi_device * dev, int bus, int slot,
        struct pci_dev **pci_dev_p)
 {
        struct pci_dev *pci_dev = NULL;
-       const struct pci_device_id *pci_id;
 
        *pci_dev_p = NULL;
 
-       /* Look for PCI table entry for this model. */
-       for (pci_id = dio200_pci_table; pci_id->vendor != 0; pci_id++) {
-               if (pci_id->driver_data == thisboard->model)
-                       break;
-       }
-       if (pci_id->vendor == 0) {
-               printk(KERN_ERR
-                       "comedi%d: %s: BUG! cannot determine board type!\n",
-                       dev->minor, DIO200_DRIVER_NAME);
-               return -EINVAL;
-       }
-
        /* Look for matching PCI device. */
-       for (pci_dev = pci_get_device(pci_id->vendor, pci_id->device, NULL);
+       for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL);
                pci_dev != NULL;
-               pci_dev = pci_get_device(pci_id->vendor,
-                       pci_id->device, pci_dev)) {
+               pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON,
+                       PCI_ANY_ID, pci_dev)) {
                /* If bus/slot specified, check them. */
                if (bus || slot) {
                        if (bus != pci_dev->bus->number
                                || slot != PCI_SLOT(pci_dev->devfn))
                                continue;
                }
-#if 0
-               if (pci_id->subvendor != PCI_ANY_ID) {
-                       if (pci_dev->subsystem_vendor != pci_id->subvendor)
+               if (thisboard->model == anypci_model) {
+                       /* Match any supported model. */
+                       int i;
+
+                       for (i = 0; i < ARRAY_SIZE(dio200_boards); i++) {
+                               if (dio200_boards[i].bustype != pci_bustype)
+                                       continue;
+                               if (pci_dev->device == dio200_boards[i].devid) {
+                                       /* Change board_ptr to matched board. */
+                                       dev->board_ptr = &dio200_boards[i];
+                                       break;
+                               }
+                       }
+                       if (i == ARRAY_SIZE(dio200_boards))
                                continue;
-               }
-               if (pci_id->subdevice != PCI_ANY_ID) {
-                       if (pci_dev->subsystem_device != pci_id->subdevice)
+               } else {
+                       /* Match specific model name. */
+                       if (pci_dev->device != thisboard->devid)
                                continue;
                }
-#endif
-               if (((pci_dev->class ^ pci_id->class) & pci_id->class_mask) !=
-                       0)
-                       continue;
 
                /* Found a match. */
                *pci_dev_p = pci_dev;
index 7ca5090344d3060b2b9dc9d54803a8ab0173b0c0..a53210c2a7b31eddc2948559312b3c560a639576 100644 (file)
@@ -26,8 +26,8 @@
 Driver: amplc_pc236
 Description: Amplicon PC36AT, PCI236
 Author: Ian Abbott <abbotti@mev.co.uk>
-Devices: [Amplicon] PC36AT (pc36at), PCI236 (pci236)
-Updated: Fri, 23 Aug 2002 11:41:11 +0100
+Devices: [Amplicon] PC36AT (pc36at), PCI236 (pci236 or amplc_pc236)
+Updated: Wed, 22 Oct 2008 13:40:03 +0100
 Status: works
 
 Configuration options - PC36AT:
@@ -64,6 +64,7 @@ unused.
 /* PCI236 PCI configuration register information */
 #define PCI_VENDOR_ID_AMPLICON 0x14dc
 #define PCI_DEVICE_ID_AMPLICON_PCI236 0x0009
+#define PCI_DEVICE_ID_INVALID 0xffff
 
 /* PC36AT / PCI236 registers */
 
@@ -93,11 +94,12 @@ unused.
  */
 
 enum pc236_bustype { isa_bustype, pci_bustype };
-enum pc236_model { pc36at_model, pci236_model };
+enum pc236_model { pc36at_model, pci236_model, anypci_model };
 
 typedef struct pc236_board_struct {
        const char *name;
        const char *fancy_name;
+       unsigned short devid;
        enum pc236_bustype bustype;
        enum pc236_model model;
 } pc236_board;
@@ -112,16 +114,26 @@ static const pc236_board pc236_boards[] = {
        {
              name:     "pci236",
              fancy_name:"PCI236",
+             devid:    PCI_DEVICE_ID_AMPLICON_PCI236,
              bustype:  pci_bustype,
              model:    pci236_model,
                },
 #endif
+#ifdef CONFIG_COMEDI_PCI
+       {
+             name:     PC236_DRIVER_NAME,
+             fancy_name:PC236_DRIVER_NAME,
+             devid:    PCI_DEVICE_ID_INVALID,
+             bustype:  pci_bustype,
+             model:    anypci_model,   /* wildcard */
+               },
+#endif
 };
 
 #ifdef CONFIG_COMEDI_PCI
 static DEFINE_PCI_DEVICE_TABLE(pc236_pci_table) = {
        {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI236, PCI_ANY_ID,
-               PCI_ANY_ID, 0, 0, pci236_model},
+               PCI_ANY_ID, 0, 0, 0},
        {0}
 };
 
@@ -165,9 +177,14 @@ static comedi_driver driver_amplc_pc236 = {
       num_names:sizeof(pc236_boards) / sizeof(pc236_board),
 };
 
+#ifdef CONFIG_COMEDI_PCI
 COMEDI_PCI_INITCLEANUP(driver_amplc_pc236, pc236_pci_table);
+#else
+COMEDI_INITCLEANUP(driver_amplc_pc236);
+#endif
 
-static int pc236_request_region(unsigned long from, unsigned long extent);
+static int pc236_request_region(unsigned minor, unsigned long from,
+       unsigned long extent);
 static void pc236_intr_disable(comedi_device * dev);
 static void pc236_intr_enable(comedi_device * dev);
 static int pc236_intr_check(comedi_device * dev);
@@ -179,6 +196,68 @@ static int pc236_intr_cmd(comedi_device * dev, comedi_subdevice * s);
 static int pc236_intr_cancel(comedi_device * dev, comedi_subdevice * s);
 static irqreturn_t pc236_interrupt(int irq, void *d PT_REGS_ARG);
 
+/*
+ * This function looks for a PCI device matching the requested board name,
+ * bus and slot.
+ */
+#ifdef CONFIG_COMEDI_PCI
+static int
+pc236_find_pci(comedi_device * dev, int bus, int slot,
+       struct pci_dev **pci_dev_p)
+{
+       struct pci_dev *pci_dev = NULL;
+
+       *pci_dev_p = NULL;
+
+       /* Look for matching PCI device. */
+       for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL);
+               pci_dev != NULL;
+               pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON,
+                       PCI_ANY_ID, pci_dev)) {
+               /* If bus/slot specified, check them. */
+               if (bus || slot) {
+                       if (bus != pci_dev->bus->number
+                               || slot != PCI_SLOT(pci_dev->devfn))
+                               continue;
+               }
+               if (thisboard->model == anypci_model) {
+                       /* Match any supported model. */
+                       int i;
+
+                       for (i = 0; i < ARRAY_SIZE(pc236_boards); i++) {
+                               if (pc236_boards[i].bustype != pci_bustype)
+                                       continue;
+                               if (pci_dev->device == pc236_boards[i].devid) {
+                                       /* Change board_ptr to matched board. */
+                                       dev->board_ptr = &pc236_boards[i];
+                                       break;
+                               }
+                       }
+                       if (i == ARRAY_SIZE(pc236_boards))
+                               continue;
+               } else {
+                       /* Match specific model name. */
+                       if (pci_dev->device != thisboard->devid)
+                               continue;
+               }
+
+               /* Found a match. */
+               *pci_dev_p = pci_dev;
+               return 0;
+       }
+       /* No match found. */
+       if (bus || slot) {
+               printk(KERN_ERR
+                       "comedi%d: error! no %s found at pci %02x:%02x!\n",
+                       dev->minor, thisboard->name, bus, slot);
+       } else {
+               printk(KERN_ERR "comedi%d: error! no %s found!\n",
+                       dev->minor, thisboard->name);
+       }
+       return -EIO;
+}
+#endif
+
 /*
  * Attach is called by the Comedi core to configure the driver
  * for a particular board.  If you specified a board_name array
@@ -193,18 +272,19 @@ static int pc236_attach(comedi_device * dev, comedi_devconfig * it)
 #ifdef CONFIG_COMEDI_PCI
        struct pci_dev *pci_dev = NULL;
        int bus = 0, slot = 0;
-       const struct pci_device_id *pci_id;
 #endif
        int share_irq = 0;
        int ret;
 
-       printk("comedi%d: %s: ", dev->minor, PC236_DRIVER_NAME);
+       printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor,
+               PC236_DRIVER_NAME);
 /*
  * Allocate the private structure area.  alloc_private() is a
  * convenient macro defined in comedidev.h.
  */
        if ((ret = alloc_private(dev, sizeof(pc236_private))) < 0) {
-               printk("out of memory!\n");
+               printk(KERN_ERR "comedi%d: error! out of memory!\n",
+                       dev->minor);
                return ret;
        }
        /* Process options. */
@@ -220,54 +300,15 @@ static int pc236_attach(comedi_device * dev, comedi_devconfig * it)
                slot = it->options[1];
                share_irq = 1;
 
-               /* Look for PCI table entry for this model. */
-               for (pci_id = pc236_pci_table; pci_id->vendor != 0; pci_id++) {
-                       if (pci_id->driver_data == thisboard->model)
-                               break;
-               }
-               if (pci_id->vendor == 0) {
-                       printk("bug! cannot determine board type!\n");
-                       return -EINVAL;
-               }
-
-               /* Look for matching PCI device. */
-               for (pci_dev = pci_get_device(pci_id->vendor, pci_id->device,
-                               NULL); pci_dev != NULL;
-                       pci_dev = pci_get_device(pci_id->vendor,
-                               pci_id->device, pci_dev)) {
-                       /* If bus/slot specified, check them. */
-                       if (bus || slot) {
-                               if (bus != pci_dev->bus->number
-                                       || slot != PCI_SLOT(pci_dev->devfn))
-                                       continue;
-                       }
-#if 0
-                       if (pci_id->subvendor != PCI_ANY_ID) {
-                               if (pci_dev->subsystem_vendor !=
-                                       pci_id->subvendor)
-                                       continue;
-                       }
-                       if (pci_id->subdevice != PCI_ANY_ID) {
-                               if (pci_dev->subsystem_device !=
-                                       pci_id->subdevice)
-                                       continue;
-                       }
-#endif
-                       if (((pci_dev->class ^ pci_id->class) & pci_id->
-                                       class_mask) != 0)
-                               continue;
-                       /* Found a match. */
-                       devpriv->pci_dev = pci_dev;
-                       break;
-               }
-               if (!pci_dev) {
-                       printk("no %s found!\n", thisboard->fancy_name);
-                       return -EIO;
-               }
+               if ((ret = pc236_find_pci(dev, bus, slot, &pci_dev)) < 0)
+                       return ret;
+               devpriv->pci_dev = pci_dev;
                break;
 #endif /* CONFIG_COMEDI_PCI */
        default:
-               printk("bug! cannot determine board type!\n");
+               printk(KERN_ERR
+                       "comedi%d: %s: BUG! cannot determine board type!\n",
+                       dev->minor, PC236_DRIVER_NAME);
                return -EINVAL;
                break;
        }
@@ -276,13 +317,14 @@ static int pc236_attach(comedi_device * dev, comedi_devconfig * it)
  * Initialize dev->board_name.
  */
        dev->board_name = thisboard->name;
-       printk("%s ", dev->board_name);
 
        /* Enable device and reserve I/O spaces. */
 #ifdef CONFIG_COMEDI_PCI
        if (pci_dev) {
                if ((ret = comedi_pci_enable(pci_dev, PC236_DRIVER_NAME)) < 0) {
-                       printk("error enabling PCI device and requesting regions!\n");
+                       printk(KERN_ERR
+                               "comedi%d: error! cannot enable PCI device and request regions!\n",
+                               dev->minor);
                        return ret;
                }
                devpriv->lcr_iobase = pci_resource_start(pci_dev, 1);
@@ -291,7 +333,8 @@ static int pc236_attach(comedi_device * dev, comedi_devconfig * it)
        } else
 #endif
        {
-               if ((ret = pc236_request_region(iobase, PC236_IO_SIZE)) < 0) {
+               ret = pc236_request_region(dev->minor, iobase, PC236_IO_SIZE);
+               if (ret < 0) {
                        return ret;
                }
        }
@@ -302,14 +345,16 @@ static int pc236_attach(comedi_device * dev, comedi_devconfig * it)
  * convenient macro defined in comedidev.h.
  */
        if ((ret = alloc_subdevices(dev, 2)) < 0) {
-               printk("out of memory!\n");
+               printk(KERN_ERR "comedi%d: error! out of memory!\n",
+                       dev->minor);
                return ret;
        }
 
        s = dev->subdevices + 0;
        /* digital i/o subdevice (8255) */
        if ((ret = subdev_8255_init(dev, s, NULL, iobase)) < 0) {
-               printk("out of memory!\n");
+               printk(KERN_ERR "comedi%d: error! out of memory!\n",
+                       dev->minor);
                return ret;
        }
        s = dev->subdevices + 1;
@@ -333,6 +378,7 @@ static int pc236_attach(comedi_device * dev, comedi_devconfig * it)
                        s->cancel = pc236_intr_cancel;
                }
        }
+       printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name);
        if (thisboard->bustype == isa_bustype) {
                printk("(base %#lx) ", iobase);
        } else {
@@ -361,7 +407,8 @@ static int pc236_attach(comedi_device * dev, comedi_devconfig * it)
  */
 static int pc236_detach(comedi_device * dev)
 {
-       printk("comedi%d: %s: remove\n", dev->minor, PC236_DRIVER_NAME);
+       printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor,
+               PC236_DRIVER_NAME);
        if (devpriv) {
                pc236_intr_disable(dev);
        }
@@ -385,6 +432,10 @@ static int pc236_detach(comedi_device * dev)
                        }
                }
        }
+       if (dev->board_name) {
+               printk(KERN_INFO "comedi%d: %s removed\n",
+                       dev->minor, dev->board_name);
+       }
        return 0;
 }
 
@@ -392,10 +443,12 @@ static int pc236_detach(comedi_device * dev)
  * This function checks and requests an I/O region, reporting an error
  * if there is a conflict.
  */
-static int pc236_request_region(unsigned long from, unsigned long extent)
+static int pc236_request_region(unsigned minor, unsigned long from,
+       unsigned long extent)
 {
        if (!from || !request_region(from, extent, PC236_DRIVER_NAME)) {
-               printk("I/O port conflict (%#lx,%lu)!\n", from, extent);
+               printk(KERN_ERR "comedi%d: I/O port conflict (%#lx,%lu)!\n",
+                       minor, from, extent);
                return -EIO;
        }
        return 0;
index 92d8c7ee3601d14892e4e62e30eb7c03a0f8e66a..75746ad21813b3e533cb11d17e5c7dc637110638 100644 (file)
@@ -26,8 +26,8 @@
 Driver: amplc_pc263
 Description: Amplicon PC263, PCI263
 Author: Ian Abbott <abbotti@mev.co.uk>
-Devices: [Amplicon] PC263 (pc263), PCI263 (pci263)
-Updated: Tue, 20 Aug 2002 11:41:01 +0100
+Devices: [Amplicon] PC263 (pc263), PCI263 (pci263 or amplc_pc263)
+Updated: Wed, 22 Oct 2008 14:10:53 +0100
 Status: works
 
 Configuration options - PC263:
@@ -53,6 +53,7 @@ The state of the outputs can be read.
 /* PCI263 PCI configuration register information */
 #define PCI_VENDOR_ID_AMPLICON 0x14dc
 #define PCI_DEVICE_ID_AMPLICON_PCI263 0x000c
+#define PCI_DEVICE_ID_INVALID 0xffff
 
 /* PC263 / PCI263 registers */
 #define PC263_IO_SIZE  2
@@ -62,11 +63,12 @@ The state of the outputs can be read.
  */
 
 enum pc263_bustype { isa_bustype, pci_bustype };
-enum pc263_model { pc263_model, pci263_model };
+enum pc263_model { pc263_model, pci263_model, anypci_model };
 
 typedef struct pc263_board_struct {
        const char *name;
        const char *fancy_name;
+       unsigned short devid;
        enum pc263_bustype bustype;
        enum pc263_model model;
 } pc263_board;
@@ -81,16 +83,26 @@ static const pc263_board pc263_boards[] = {
        {
              name:     "pci263",
              fancy_name:"PCI263",
+             devid:    PCI_DEVICE_ID_AMPLICON_PCI263,
              bustype:  pci_bustype,
              model:    pci263_model,
                },
 #endif
+#ifdef CONFIG_COMEDI_PCI
+       {
+             name:     PC263_DRIVER_NAME,
+             fancy_name:PC263_DRIVER_NAME,
+             devid:    PCI_DEVICE_ID_INVALID,
+             bustype:  pci_bustype,
+             model:    anypci_model,   /* wildcard */
+               },
+#endif
 };
 
 #ifdef CONFIG_COMEDI_PCI
 static DEFINE_PCI_DEVICE_TABLE(pc263_pci_table) = {
        {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI263, PCI_ANY_ID,
-               PCI_ANY_ID, 0, 0, pci263_model},
+               PCI_ANY_ID, 0, 0, 0},
        {0}
 };
 
@@ -132,12 +144,75 @@ static comedi_driver driver_amplc_pc263 = {
       num_names:sizeof(pc263_boards) / sizeof(pc263_board),
 };
 
-static int pc263_request_region(unsigned long from, unsigned long extent);
+static int pc263_request_region(unsigned minor, unsigned long from,
+       unsigned long extent);
 static int pc263_dio_insn_bits(comedi_device * dev, comedi_subdevice * s,
        comedi_insn * insn, lsampl_t * data);
 static int pc263_dio_insn_config(comedi_device * dev, comedi_subdevice * s,
        comedi_insn * insn, lsampl_t * data);
 
+/*
+ * This function looks for a PCI device matching the requested board name,
+ * bus and slot.
+ */
+#ifdef CONFIG_COMEDI_PCI
+static int
+pc263_find_pci(comedi_device * dev, int bus, int slot,
+       struct pci_dev **pci_dev_p)
+{
+       struct pci_dev *pci_dev = NULL;
+
+       *pci_dev_p = NULL;
+
+       /* Look for matching PCI device. */
+       for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL);
+               pci_dev != NULL;
+               pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON,
+                       PCI_ANY_ID, pci_dev)) {
+               /* If bus/slot specified, check them. */
+               if (bus || slot) {
+                       if (bus != pci_dev->bus->number
+                               || slot != PCI_SLOT(pci_dev->devfn))
+                               continue;
+               }
+               if (thisboard->model == anypci_model) {
+                       /* Match any supported model. */
+                       int i;
+
+                       for (i = 0; i < ARRAY_SIZE(pc263_boards); i++) {
+                               if (pc263_boards[i].bustype != pci_bustype)
+                                       continue;
+                               if (pci_dev->device == pc263_boards[i].devid) {
+                                       /* Change board_ptr to matched board. */
+                                       dev->board_ptr = &pc263_boards[i];
+                                       break;
+                               }
+                       }
+                       if (i == ARRAY_SIZE(pc263_boards))
+                               continue;
+               } else {
+                       /* Match specific model name. */
+                       if (pci_dev->device != thisboard->devid)
+                               continue;
+               }
+
+               /* Found a match. */
+               *pci_dev_p = pci_dev;
+               return 0;
+       }
+       /* No match found. */
+       if (bus || slot) {
+               printk(KERN_ERR
+                       "comedi%d: error! no %s found at pci %02x:%02x!\n",
+                       dev->minor, thisboard->name, bus, slot);
+       } else {
+               printk(KERN_ERR "comedi%d: error! no %s found!\n",
+                       dev->minor, thisboard->name);
+       }
+       return -EIO;
+}
+#endif
+
 /*
  * Attach is called by the Comedi core to configure the driver
  * for a particular board.  If you specified a board_name array
@@ -151,18 +226,19 @@ static int pc263_attach(comedi_device * dev, comedi_devconfig * it)
 #ifdef CONFIG_COMEDI_PCI
        struct pci_dev *pci_dev = NULL;
        int bus = 0, slot = 0;
-       const struct pci_device_id *pci_id;
 #endif
        int ret;
 
-       printk("comedi%d: %s: ", dev->minor, PC263_DRIVER_NAME);
+       printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor,
+               PC263_DRIVER_NAME);
 /*
  * Allocate the private structure area.  alloc_private() is a
  * convenient macro defined in comedidev.h.
  */
 #ifdef CONFIG_COMEDI_PCI
        if ((ret = alloc_private(dev, sizeof(pc263_private))) < 0) {
-               printk("out of memory!\n");
+               printk(KERN_ERR "comedi%d: error! out of memory!\n",
+                       dev->minor);
                return ret;
        }
 #endif
@@ -176,54 +252,15 @@ static int pc263_attach(comedi_device * dev, comedi_devconfig * it)
                bus = it->options[0];
                slot = it->options[1];
 
-               /* Look for PCI table entry for this model. */
-               for (pci_id = pc263_pci_table; pci_id->vendor != 0; pci_id++) {
-                       if (pci_id->driver_data == thisboard->model)
-                               break;
-               }
-               if (pci_id->vendor == 0) {
-                       printk("bug! cannot determine board type!\n");
-                       return -EINVAL;
-               }
-
-               /* Look for matching PCI device. */
-               for (pci_dev = pci_get_device(pci_id->vendor, pci_id->device,
-                               NULL); pci_dev != NULL;
-                       pci_dev = pci_get_device(pci_id->vendor,
-                               pci_id->device, pci_dev)) {
-                       /* If bus/slot specified, check them. */
-                       if (bus || slot) {
-                               if (bus != pci_dev->bus->number
-                                       || slot != PCI_SLOT(pci_dev->devfn))
-                                       continue;
-                       }
-#if 0
-                       if (pci_id->subvendor != PCI_ANY_ID) {
-                               if (pci_dev->subsystem_vendor !=
-                                       pci_id->subvendor)
-                                       continue;
-                       }
-                       if (pci_id->subdevice != PCI_ANY_ID) {
-                               if (pci_dev->subsystem_device !=
-                                       pci_id->subdevice)
-                                       continue;
-                       }
-#endif
-                       if (((pci_dev->class ^ pci_id->class) & pci_id->
-                                       class_mask) != 0)
-                               continue;
-                       /* Found a match. */
-                       devpriv->pci_dev = pci_dev;
-                       break;
-               }
-               if (!pci_dev) {
-                       printk("no %s found!\n", thisboard->fancy_name);
-                       return -EIO;
-               }
+               if ((ret = pc263_find_pci(dev, bus, slot, &pci_dev)) < 0)
+                       return ret;
+               devpriv->pci_dev = pci_dev;
                break;
 #endif /* CONFIG_COMEDI_PCI */
        default:
-               printk("bug! cannot determine board type!\n");
+               printk(KERN_ERR
+                       "comedi%d: %s: BUG! cannot determine board type!\n",
+                       dev->minor, PC263_DRIVER_NAME);
                return -EINVAL;
                break;
        }
@@ -232,20 +269,22 @@ static int pc263_attach(comedi_device * dev, comedi_devconfig * it)
  * Initialize dev->board_name.
  */
        dev->board_name = thisboard->name;
-       printk("%s ", dev->board_name);
 
        /* Enable device and reserve I/O spaces. */
 #ifdef CONFIG_COMEDI_PCI
        if (pci_dev) {
                if ((ret = comedi_pci_enable(pci_dev, PC263_DRIVER_NAME)) < 0) {
-                       printk("error enabling PCI device and requesting regions!\n");
+                       printk(KERN_ERR
+                               "comedi%d: error! cannot enable PCI device and request regions!\n",
+                               dev->minor);
                        return ret;
                }
                iobase = pci_resource_start(pci_dev, 2);
        } else
 #endif
        {
-               if ((ret = pc263_request_region(iobase, PC263_IO_SIZE)) < 0) {
+               ret = pc263_request_region(dev->minor, iobase, PC263_IO_SIZE);
+               if (ret < 0) {
                        return ret;
                }
        }
@@ -256,8 +295,9 @@ static int pc263_attach(comedi_device * dev, comedi_devconfig * it)
  * convenient macro defined in comedidev.h.
  */
        if ((ret = alloc_subdevices(dev, 1)) < 0) {
-               printk("out of memory!\n");
-               return -ENOMEM;
+               printk(KERN_ERR "comedi%d: error! out of memory!\n",
+                       dev->minor);
+               return ret;
        }
 
        s = dev->subdevices + 0;
@@ -275,6 +315,7 @@ static int pc263_attach(comedi_device * dev, comedi_devconfig * it)
        s->state = inb(dev->iobase);
        s->state = s->state | (inb(dev->iobase) << 8);
 
+       printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name);
        if (thisboard->bustype == isa_bustype) {
                printk("(base %#lx) ", iobase);
        } else {
@@ -298,7 +339,8 @@ static int pc263_attach(comedi_device * dev, comedi_devconfig * it)
  */
 static int pc263_detach(comedi_device * dev)
 {
-       printk("comedi%d: %s: remove\n", dev->minor, PC263_DRIVER_NAME);
+       printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor,
+               PC263_DRIVER_NAME);
 
 #ifdef CONFIG_COMEDI_PCI
        if (devpriv)
@@ -318,7 +360,10 @@ static int pc263_detach(comedi_device * dev)
                        }
                }
        }
-
+       if (dev->board_name) {
+               printk(KERN_INFO "comedi%d: %s removed\n",
+                       dev->minor, dev->board_name);
+       }
        return 0;
 }
 
@@ -326,10 +371,12 @@ static int pc263_detach(comedi_device * dev)
  * This function checks and requests an I/O region, reporting an error
  * if there is a conflict.
  */
-static int pc263_request_region(unsigned long from, unsigned long extent)
+static int pc263_request_region(unsigned minor, unsigned long from,
+       unsigned long extent)
 {
-       if (!request_region(from, extent, PC263_DRIVER_NAME)) {
-               printk("I/O port conflict (%#lx,%lu)!\n", from, extent);
+       if (!from || !request_region(from, extent, PC263_DRIVER_NAME)) {
+               printk(KERN_ERR "comedi%d: I/O port conflict (%#lx,%lu)!\n",
+                       minor, from, extent);
                return -EIO;
        }
        return 0;
@@ -377,4 +424,8 @@ static int pc263_dio_insn_config(comedi_device * dev, comedi_subdevice * s,
  * A convenient macro that defines init_module() and cleanup_module(),
  * as necessary.
  */
+#ifdef CONFIG_COMEDI_PCI
 COMEDI_PCI_INITCLEANUP(driver_amplc_pc263, pc263_pci_table);
+#else
+COMEDI_INITCLEANUP(driver_amplc_pc263);
+#endif
index e2788d87c14b0e5c20d90c70fd63e8f0321b6b7c..63b7c34a9a0447e068addfe8dd8c2c6f7af79145 100644 (file)
@@ -26,8 +26,9 @@
 Driver: amplc_pci224
 Description: Amplicon PCI224, PCI234
 Author: Ian Abbott <abbotti@mev.co.uk>
-Devices: [Amplicon] PCI224 (pci224), PCI234 (pci234)
-Updated: Thu, 24 Feb 2005 12:29:26 +0000
+Devices: [Amplicon] PCI224 (amplc_pci224 or pci224),
+  PCI234 (amplc_pci224 or pci234)
+Updated: Wed, 22 Oct 2008 12:25:08 +0100
 Status: works, but see caveats
 
 Supports:
@@ -117,6 +118,7 @@ Caveats:
 /* #define PCI_VENDOR_ID_AMPLICON 0x14dc */
 #define PCI_DEVICE_ID_AMPLICON_PCI224 0x0007
 #define PCI_DEVICE_ID_AMPLICON_PCI234 0x0008
+#define PCI_DEVICE_ID_INVALID 0xffff
 
 /*
  * PCI224/234 i/o space 1 (PCIBAR2) registers.
@@ -342,10 +344,11 @@ static const unsigned short hwrange_pci234[1] = {
  * Board descriptions.
  */
 
-enum pci224_model { pci224_model, pci234_model };
+enum pci224_model { any_model, pci224_model, pci234_model };
 
 typedef struct pci224_board_struct {
        const char *name;
+       unsigned short devid;
        enum pci224_model model;
        unsigned int ao_chans;
        unsigned int ao_bits;
@@ -354,16 +357,23 @@ typedef struct pci224_board_struct {
 static const pci224_board pci224_boards[] = {
        {
              name:     "pci224",
+             devid: PCI_DEVICE_ID_AMPLICON_PCI224,
              model:    pci224_model,
              ao_chans:16,
              ao_bits:  12,
                },
        {
              name:     "pci234",
+             devid: PCI_DEVICE_ID_AMPLICON_PCI234,
              model:    pci234_model,
              ao_chans:4,
              ao_bits:  16,
                },
+       {
+             name:     DRIVER_NAME,
+             devid: PCI_DEVICE_ID_INVALID,
+             model:    any_model,      /* wildcard */
+               },
 };
 
 /*
@@ -372,9 +382,9 @@ static const pci224_board pci224_boards[] = {
 
 static DEFINE_PCI_DEVICE_TABLE(pci224_pci_table) = {
        {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI224,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0, pci224_model},
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
        {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI234,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0, pci234_model},
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
        {0}
 };
 
@@ -1258,46 +1268,38 @@ pci224_find_pci(comedi_device * dev, int bus, int slot,
        struct pci_dev **pci_dev_p)
 {
        struct pci_dev *pci_dev = NULL;
-       const struct pci_device_id *pci_id;
 
        *pci_dev_p = NULL;
 
-       /* Look for PCI table entry for this model. */
-       for (pci_id = pci224_pci_table; pci_id->vendor != 0; pci_id++) {
-               if (pci_id->driver_data == thisboard->model)
-                       break;
-       }
-       if (pci_id->vendor == 0) {
-               printk(KERN_ERR "comedi%d: %s: BUG! "
-                       "cannot determine board type!\n",
-                       dev->minor, DRIVER_NAME);
-               return -EINVAL;
-       }
-
        /* Look for matching PCI device. */
-       for (pci_dev = pci_get_device(pci_id->vendor, pci_id->device, NULL);
+       for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL);
                pci_dev != NULL;
-               pci_dev = pci_get_device(pci_id->vendor,
-                       pci_id->device, pci_dev)) {
+               pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID,
+                       pci_dev)) {
                /* If bus/slot specified, check them. */
                if (bus || slot) {
                        if (bus != pci_dev->bus->number
                                || slot != PCI_SLOT(pci_dev->devfn))
                                continue;
                }
-#if 0
-               if (pci_id->subvendor != PCI_ANY_ID) {
-                       if (pci_dev->subsystem_vendor != pci_id->subvendor)
+               if (thisboard->model == any_model) {
+                       /* Match any supported model. */
+                       int i;
+
+                       for (i = 0; i < ARRAY_SIZE(pci224_boards); i++) {
+                               if (pci_dev->device == pci224_boards[i].devid) {
+                                       /* Change board_ptr to matched board. */
+                                       dev->board_ptr = &pci224_boards[i];
+                                       break;
+                               }
+                       }
+                       if (i == ARRAY_SIZE(pci224_boards))
                                continue;
-               }
-               if (pci_id->subdevice != PCI_ANY_ID) {
-                       if (pci_dev->subsystem_device != pci_id->subdevice)
+               } else {
+                       /* Match specific model name. */
+                       if (thisboard->devid != pci_dev->device)
                                continue;
                }
-#endif
-               if (((pci_dev->class ^ pci_id->class) & pci_id->class_mask) !=
-                       0)
-                       continue;
 
                /* Found a match. */
                *pci_dev_p = pci_dev;