From: Ian Abbott Date: Wed, 22 Oct 2008 14:01:40 +0000 (+0000) Subject: Support autoconfiguration of PCI devices in some Amplicon drivers. X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=21c3c6f57bc2527193f1929c0919f95b7352cd33;p=comedi.git Support autoconfiguration of PCI devices in some Amplicon drivers. --- diff --git a/comedi/drivers/amplc_dio200.c b/comedi/drivers/amplc_dio200.c index fe2ee77a..228291a5 100644 --- a/comedi/drivers/amplc_dio200.c +++ b/comedi/drivers/amplc_dio200.c @@ -29,8 +29,9 @@ Driver: amplc_dio200 Description: Amplicon 200 Series Digital I/O Author: Ian Abbott 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; diff --git a/comedi/drivers/amplc_pc236.c b/comedi/drivers/amplc_pc236.c index 7ca50903..a53210c2 100644 --- a/comedi/drivers/amplc_pc236.c +++ b/comedi/drivers/amplc_pc236.c @@ -26,8 +26,8 @@ Driver: amplc_pc236 Description: Amplicon PC36AT, PCI236 Author: Ian Abbott -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; diff --git a/comedi/drivers/amplc_pc263.c b/comedi/drivers/amplc_pc263.c index 92d8c7ee..75746ad2 100644 --- a/comedi/drivers/amplc_pc263.c +++ b/comedi/drivers/amplc_pc263.c @@ -26,8 +26,8 @@ Driver: amplc_pc263 Description: Amplicon PC263, PCI263 Author: Ian Abbott -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 diff --git a/comedi/drivers/amplc_pci224.c b/comedi/drivers/amplc_pci224.c index e2788d87..63b7c34a 100644 --- a/comedi/drivers/amplc_pci224.c +++ b/comedi/drivers/amplc_pci224.c @@ -26,8 +26,9 @@ Driver: amplc_pci224 Description: Amplicon PCI224, PCI234 Author: Ian Abbott -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;