patch-2.3.99-pre1 linux/drivers/ide/ide-pnp.c

Next file: linux/drivers/ide/ide-probe.c
Previous file: linux/drivers/ide/ide-pmac.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.51/linux/drivers/ide/ide-pnp.c linux/drivers/ide/ide-pnp.c
@@ -0,0 +1,158 @@
+/*
+ * linux/drivers/block/ide-pnp.c
+ *
+ * This file provides autodetection for ISA PnP IDE interfaces.
+ * It was tested with "ESS ES1868 Plug and Play AudioDrive" IDE interface.
+ *
+ * Copyright (C) 2000 Andrey Panin <pazke@orbita.don.sitek.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * You should have received a copy of the GNU General Public License
+ * (for example /usr/src/linux/COPYING); if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  
+ */
+
+#include <linux/ide.h>
+#include <linux/isapnp.h>
+
+#ifndef PREPARE_FUNC
+#define PREPARE_FUNC(dev)  (dev->prepare)
+#define ACTIVATE_FUNC(dev)  (dev->activate)
+#define DEACTIVATE_FUNC(dev)  (dev->deactivate)
+#endif
+
+#define DEV_IO(dev, index) (dev->resource[index].start)
+#define DEV_IRQ(dev, index) (dev->irq_resource[index].start)
+
+#define DEV_NAME(dev) (dev->bus->name ? dev->bus->name : "ISA PnP")
+
+#define GENERIC_HD_DATA		0
+#define GENERIC_HD_ERROR	1
+#define GENERIC_HD_NSECTOR	2
+#define GENERIC_HD_SECTOR	3
+#define GENERIC_HD_LCYL		4
+#define GENERIC_HD_HCYL		5
+#define GENERIC_HD_SELECT	6
+#define GENERIC_HD_STATUS	7
+
+static int generic_ide_offsets[IDE_NR_PORTS] __initdata = {
+	GENERIC_HD_DATA, GENERIC_HD_ERROR, GENERIC_HD_NSECTOR, 
+	GENERIC_HD_SECTOR, GENERIC_HD_LCYL, GENERIC_HD_HCYL,
+	GENERIC_HD_SELECT, GENERIC_HD_STATUS, -1, -1
+};
+
+/* ISA PnP device table entry */
+struct pnp_dev_t {
+	unsigned int vendor, device;
+	int (*init_fn)(struct pci_dev *dev, int enable);
+};
+
+/* Generic initialisation function for ISA PnP IDE interface */
+static int __init pnpide_generic_init(struct pci_dev *dev, int enable)
+{
+	hw_regs_t hw;
+	int index;
+
+	if (!enable)
+		return 0;
+
+	if (!(DEV_IO(dev, 0) && DEV_IO(dev, 1) && DEV_IRQ(dev, 0)))
+		return 1;
+
+	ide_setup_ports(&hw, (ide_ioreg_t) DEV_IO(dev, 0),
+			generic_ide_offsets, (ide_ioreg_t) DEV_IO(dev, 1),
+			0, NULL, DEV_IRQ(dev, 0));
+
+	index = ide_register_hw(&hw, NULL);
+
+	if (index != -1) {
+	    	printk("ide%d: %s IDE interface\n", index, DEV_NAME(dev));
+		return 0;
+	}
+
+	return 1;
+}
+
+/* Add your devices here :)) */
+struct pnp_dev_t idepnp_devices[] __initdata = {
+	/* Generic ESDI/IDE/ATA compatible hard disk controller
 */
+	{	ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0x0600),
+		pnpide_generic_init },
+	{	0 }
+};
+
+#ifdef MODULE
+#define NR_PNP_DEVICES 8
+struct pnp_dev_inst {
+	struct pci_dev *dev;
+	struct pnp_dev_t *dev_type;
+};
+static struct pnp_dev_inst devices[NR_PNP_DEVICES];
+static int pnp_ide_dev_idx = 0;
+#endif
+
+/*
+ * Probe for ISA PnP IDE interfaces.
+ */
+void pnpide_init(int enable)
+{
+	struct pci_dev *dev = NULL;
+	struct pnp_dev_t *dev_type;
+
+	if (!isapnp_present())
+		return;
+
+#ifdef MODULE
+	/* Module unload, deactivate all registered devices. */
+	if (!enable) {
+		int i;
+		for (i = 0; i < pnp_ide_dev_idx; i++) {
+			devices[i].dev_type->init_fn(dev, 0);
+
+			if (DEACTIVATE_FUNC(devices[i].dev))
+				DEACTIVATE_FUNC(devices[i].dev)(devices[i].dev);
+		}
+		return;
+	}
+#endif
+	for (dev_type = idepnp_devices; dev_type->vendor; dev_type++) {
+		while ((dev = isapnp_find_dev(NULL, dev_type->vendor,
+			dev_type->device, dev))) {
+
+			if (dev->active)
+				continue;
+
+       			if (PREPARE_FUNC(dev) && (PREPARE_FUNC(dev))(dev) < 0) {
+				printk("ide: %s prepare failed\n", DEV_NAME(dev));
+				continue;
+			}
+
+			if (ACTIVATE_FUNC(dev) && (ACTIVATE_FUNC(dev))(dev) < 0) {
+				printk("ide: %s activate failed\n", DEV_NAME(dev));
+				continue;
+			}
+
+			/* Call device initialization function */
+			if (dev_type->init_fn(dev, 1)) {
+				if (DEACTIVATE_FUNC(dev))
+					DEACTIVATE_FUNC(dev)(dev);
+			} else {
+#ifdef MODULE
+				/*
+				 * Register device in the array to
+				 * deactivate it on a module unload.
+				 */
+				if (pnp_ide_dev_idx >= NR_PNP_DEVICES)
+					return;
+				devices[pnp_ide_dev_idx].dev = dev;
+				devices[pnp_ide_dev_idx].dev_type = dev_type;
+				pnp_ide_dev_idx++;
+#endif
+			}
+		}
+	}
+}

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)