+
+ iface->base = pci_resource_start(iface->pdev, iface->bar);
+ rc = scx200_acb_create(iface);
+
+ if (rc == 0)
+ return 0;
+
+ pci_release_region(iface->pdev, iface->bar);
+ pci_dev_put(iface->pdev);
+ errout_free:
+ kfree(iface);
+ return rc;
+}
+
+static int __init scx200_create_isa(const char *text, unsigned long base,
+ int index)
+{
+ struct scx200_acb_iface *iface;
+ int rc;
+
+ iface = scx200_create_iface(text, index);
+
+ if (iface == NULL)
+ return -ENOMEM;
+
+ if (request_region(base, 8, iface->adapter.name) == 0) {
+ printk(KERN_ERR NAME ": can't allocate io 0x%lx-0x%lx\n",
+ base, base + 8 - 1);
+ rc = -EBUSY;
+ goto errout_free;
+ }
+
+ iface->base = base;
+ rc = scx200_acb_create(iface);
+
+ if (rc == 0)
+ return 0;
+
+ release_region(base, 8);
+ errout_free:
+ kfree(iface);
+ return rc;
+}
+
+/* Driver data is an index into the scx200_data array that indicates
+ * the name and the BAR where the I/O address resource is located. ISA
+ * devices are flagged with a bar value of -1 */
+
+static struct pci_device_id scx200_pci[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE),
+ .driver_data = 0 },
+ { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE),
+ .driver_data = 0 },
+ { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA),
+ .driver_data = 1 },
+ { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA),
+ .driver_data = 2 }
+};
+
+static struct {
+ const char *name;
+ int bar;
+} scx200_data[] = {
+ { "SCx200", -1 },
+ { "CS5535", 0 },
+ { "CS5536", 0 }
+};
+
+static __init int scx200_scan_pci(void)
+{
+ int data, dev;
+ int rc = -ENODEV;
+ struct pci_dev *pdev;
+
+ for(dev = 0; dev < ARRAY_SIZE(scx200_pci); dev++) {
+ pdev = pci_get_device(scx200_pci[dev].vendor,
+ scx200_pci[dev].device, NULL);
+
+ if (pdev == NULL)
+ continue;
+
+ data = scx200_pci[dev].driver_data;
+
+ /* if .bar is greater or equal to zero, this is a
+ * PCI device - otherwise, we assume
+ that the ports are ISA based
+ */
+
+ if (scx200_data[data].bar >= 0)
+ rc = scx200_create_pci(scx200_data[data].name, pdev,
+ scx200_data[data].bar);
+ else {
+ int i;
+
+ for (i = 0; i < MAX_DEVICES; ++i) {
+ if (base[i] == 0)
+ continue;
+
+ rc = scx200_create_isa(scx200_data[data].name,
+ base[i],
+ i);
+ }
+ }
+
+ break;
+ }
+