make oldconfig will rebuild these...
[linux-2.4.21-pre4.git] / drivers / ide / ide-pnp.c
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 #define DEV_IO(dev, index) (dev->resource[index].start)
25 #define DEV_IRQ(dev, index) (dev->irq_resource[index].start)
26
27 #define DEV_NAME(dev) (dev->bus->name ? dev->bus->name : "ISA PnP")
28
29 #define GENERIC_HD_DATA         0
30 #define GENERIC_HD_ERROR        1
31 #define GENERIC_HD_NSECTOR      2
32 #define GENERIC_HD_SECTOR       3
33 #define GENERIC_HD_LCYL         4
34 #define GENERIC_HD_HCYL         5
35 #define GENERIC_HD_SELECT       6
36 #define GENERIC_HD_STATUS       7
37
38 static int generic_ide_offsets[IDE_NR_PORTS] __initdata = {
39         GENERIC_HD_DATA, GENERIC_HD_ERROR, GENERIC_HD_NSECTOR, 
40         GENERIC_HD_SECTOR, GENERIC_HD_LCYL, GENERIC_HD_HCYL,
41         GENERIC_HD_SELECT, GENERIC_HD_STATUS, -1, -1
42 };
43
44 /* ISA PnP device table entry */
45 struct pnp_dev_t {
46         unsigned short card_vendor, card_device, vendor, device;
47         int (*init_fn)(struct pci_dev *dev, int enable);
48 };
49
50 /* Generic initialisation function for ISA PnP IDE interface */
51
52 static int __init pnpide_generic_init(struct pci_dev *dev, int enable)
53 {
54         hw_regs_t hw;
55         int index;
56
57         if (!enable)
58                 return 0;
59
60         if (!(DEV_IO(dev, 0) && DEV_IO(dev, 1) && DEV_IRQ(dev, 0)))
61                 return 1;
62
63         ide_setup_ports(&hw, (ide_ioreg_t) DEV_IO(dev, 0),
64                         generic_ide_offsets,
65                         (ide_ioreg_t) DEV_IO(dev, 1),
66                         0, NULL,
67 //                      generic_pnp_ide_iops,
68                         DEV_IRQ(dev, 0));
69
70         index = ide_register_hw(&hw, NULL);
71
72         if (index != -1) {
73                 printk(KERN_INFO "ide%d: %s IDE interface\n", index, DEV_NAME(dev));
74                 return 0;
75         }
76
77         return 1;
78 }
79
80 /* Add your devices here :)) */
81 struct pnp_dev_t idepnp_devices[] __initdata = {
82         /* Generic ESDI/IDE/ATA compatible hard disk controller */
83         {       ISAPNP_ANY_ID, ISAPNP_ANY_ID,
84                 ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0x0600),
85                 pnpide_generic_init },
86         {       0 }
87 };
88
89 #define NR_PNP_DEVICES 8
90 struct pnp_dev_inst {
91         struct pci_dev *dev;
92         struct pnp_dev_t *dev_type;
93 };
94 static struct pnp_dev_inst devices[NR_PNP_DEVICES];
95 static int pnp_ide_dev_idx = 0;
96
97 /*
98  * Probe for ISA PnP IDE interfaces.
99  */
100
101 void __init pnpide_init(int enable)
102 {
103         struct pci_dev *dev = NULL;
104         struct pnp_dev_t *dev_type;
105
106         if (!isapnp_present())
107                 return;
108
109         /* Module unload, deactivate all registered devices. */
110         if (!enable) {
111                 int i;
112                 for (i = 0; i < pnp_ide_dev_idx; i++) {
113                         dev = devices[i].dev;
114                         devices[i].dev_type->init_fn(dev, 0);
115                         if (dev->deactivate)
116                                 dev->deactivate(dev);
117                 }
118                 return;
119         }
120
121         for (dev_type = idepnp_devices; dev_type->vendor; dev_type++) {
122                 while ((dev = isapnp_find_dev(NULL, dev_type->vendor,
123                         dev_type->device, dev))) {
124
125                         if (dev->active)
126                                 continue;
127
128                         if (dev->prepare && dev->prepare(dev) < 0) {
129                                 printk(KERN_ERR"ide-pnp: %s prepare failed\n", DEV_NAME(dev));
130                                 continue;
131                         }
132
133                         if (dev->activate && dev->activate(dev) < 0) {
134                                 printk(KERN_ERR"ide: %s activate failed\n", DEV_NAME(dev));
135                                 continue;
136                         }
137
138                         /* Call device initialization function */
139                         if (dev_type->init_fn(dev, 1)) {
140                                 if (dev->deactivate(dev))
141                                         dev->deactivate(dev);
142                         } else {
143 #ifdef MODULE
144                                 /*
145                                  * Register device in the array to
146                                  * deactivate it on a module unload.
147                                  */
148                                 if (pnp_ide_dev_idx >= NR_PNP_DEVICES)
149                                         return;
150                                 devices[pnp_ide_dev_idx].dev = dev;
151                                 devices[pnp_ide_dev_idx].dev_type = dev_type;
152                                 pnp_ide_dev_idx++;
153 #endif
154                         }
155                 }
156         }
157 }