1 /*
2 * linux/drivers/ide/ide-pnp.c
3 *
4 * This file provides autodetection for ISA PnP IDE interfaces.
5 * It was tested with "ESS ES1868 Plug and Play AudioDrive" IDE interface.
6 *
7 * Copyright (C) 2000 Andrey Panin <pazke@orbita.don.sitek.net>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2, or (at your option)
12 * any later version.
13 *
14 * You should have received a copy of the GNU General Public License
15 * (for example /usr/src/linux/COPYING); if not, write to the Free
16 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19 #include <linux/ide.h>
20 #include <linux/init.h>
21
22 #include <linux/isapnp.h>
23
24 #ifndef PREPARE_FUNC
25 #define PREPARE_FUNC(dev) (dev->prepare)
26 #define ACTIVATE_FUNC(dev) (dev->activate)
27 #define DEACTIVATE_FUNC(dev) (dev->deactivate)
28 #endif
29
30 #define DEV_IO(dev, index) (dev->resource[index].start)
31 #define DEV_IRQ(dev, index) (dev->irq_resource[index].start)
32
33 #define DEV_NAME(dev) (dev->bus->name ? dev->bus->name : "ISA PnP")
34
35 #define GENERIC_HD_DATA 0
36 #define GENERIC_HD_ERROR 1
37 #define GENERIC_HD_NSECTOR 2
38 #define GENERIC_HD_SECTOR 3
39 #define GENERIC_HD_LCYL 4
40 #define GENERIC_HD_HCYL 5
41 #define GENERIC_HD_SELECT 6
42 #define GENERIC_HD_STATUS 7
43
44 static int generic_ide_offsets[IDE_NR_PORTS] __initdata = {
45 GENERIC_HD_DATA, GENERIC_HD_ERROR, GENERIC_HD_NSECTOR,
46 GENERIC_HD_SECTOR, GENERIC_HD_LCYL, GENERIC_HD_HCYL,
47 GENERIC_HD_SELECT, GENERIC_HD_STATUS, -1, -1
48 };
49
50 /* ISA PnP device table entry */
51 struct pnp_dev_t {
52 unsigned int vendor, device;
53 int (*init_fn)(struct pci_dev *dev, int enable);
54 };
55
56 /* Generic initialisation function for ISA PnP IDE interface */
57 static int __init pnpide_generic_init(struct pci_dev *dev, int enable)
58 {
59 hw_regs_t hw;
60 int index;
61
62 if (!enable)
63 return 0;
64
65 if (!(DEV_IO(dev, 0) && DEV_IO(dev, 1) && DEV_IRQ(dev, 0)))
66 return 1;
67
68 ide_setup_ports(&hw, (ide_ioreg_t) DEV_IO(dev, 0),
69 generic_ide_offsets, (ide_ioreg_t) DEV_IO(dev, 1),
70 0, NULL, DEV_IRQ(dev, 0));
71
72 index = ide_register_hw(&hw, NULL);
73
74 if (index != -1) {
75 printk("ide%d: %s IDE interface\n", index, DEV_NAME(dev));
76 return 0;
77 }
78
79 return 1;
80 }
81
82 /* Add your devices here :)) */
83 struct pnp_dev_t idepnp_devices[] __initdata = {
84 /* Generic ESDI/IDE/ATA compatible hard disk controller
*/
85 { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0x0600),
86 pnpide_generic_init },
87 { 0 }
88 };
89
90 #ifdef MODULE
91 #define NR_PNP_DEVICES 8
92 struct pnp_dev_inst {
93 struct pci_dev *dev;
94 struct pnp_dev_t *dev_type;
95 };
96 static struct pnp_dev_inst devices[NR_PNP_DEVICES];
97 static int pnp_ide_dev_idx = 0;
98 #endif
99
100 /*
101 * Probe for ISA PnP IDE interfaces.
102 */
103 void __init pnpide_init(int enable)
104 {
105 struct pci_dev *dev = NULL;
106 struct pnp_dev_t *dev_type;
107
108 if (!isapnp_present())
109 return;
110
111 #ifdef MODULE
112 /* Module unload, deactivate all registered devices. */
113 if (!enable) {
114 int i;
115 for (i = 0; i < pnp_ide_dev_idx; i++) {
116 devices[i].dev_type->init_fn(dev, 0);
117
118 if (DEACTIVATE_FUNC(devices[i].dev))
119 DEACTIVATE_FUNC(devices[i].dev)(devices[i].dev);
120 }
121 return;
122 }
123 #endif
124 for (dev_type = idepnp_devices; dev_type->vendor; dev_type++) {
125 while ((dev = isapnp_find_dev(NULL, dev_type->vendor,
126 dev_type->device, dev))) {
127
128 if (dev->active)
129 continue;
130
131 if (PREPARE_FUNC(dev) && (PREPARE_FUNC(dev))(dev) < 0) {
132 printk("ide: %s prepare failed\n", DEV_NAME(dev));
133 continue;
134 }
135
136 if (ACTIVATE_FUNC(dev) && (ACTIVATE_FUNC(dev))(dev) < 0) {
137 printk("ide: %s activate failed\n", DEV_NAME(dev));
138 continue;
139 }
140
141 /* Call device initialization function */
142 if (dev_type->init_fn(dev, 1)) {
143 if (DEACTIVATE_FUNC(dev))
144 DEACTIVATE_FUNC(dev)(dev);
145 } else {
146 #ifdef MODULE
147 /*
148 * Register device in the array to
149 * deactivate it on a module unload.
150 */
151 if (pnp_ide_dev_idx >= NR_PNP_DEVICES)
152 return;
153 devices[pnp_ide_dev_idx].dev = dev;
154 devices[pnp_ide_dev_idx].dev_type = dev_type;
155 pnp_ide_dev_idx++;
156 #endif
157 }
158 }
159 }
160 }
161
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.