Deleted Added
full compact
aha_isa.c (42887) aha_isa.c (45720)
1/*
2 * Product specific probe and attach routines for:
3 * Adaptec 154x.
4 *
5 * Derived from code written by:
6 *
7 * Copyright (c) 1998 Justin T. Gibbs
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions, and the following disclaimer,
15 * without modification, immediately at the beginning of the file.
16 * 2. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
1/*
2 * Product specific probe and attach routines for:
3 * Adaptec 154x.
4 *
5 * Derived from code written by:
6 *
7 * Copyright (c) 1998 Justin T. Gibbs
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions, and the following disclaimer,
15 * without modification, immediately at the beginning of the file.
16 * 2. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 * $Id: aha_isa.c,v 1.5 1998/11/10 06:44:54 gibbs Exp $
31 * $Id: aha_isa.c,v 1.6 1999/01/20 06:21:23 imp Exp $
32 */
33
34#include "pnp.h"
35
36#include <sys/param.h>
37#include <sys/systm.h>
38#include <sys/kernel.h>
39
40#include <machine/bus_pio.h>
41#include <machine/bus.h>
42
43#include <i386/isa/isa_device.h>
44#include <dev/aha/ahareg.h>
45
46#include <cam/scsi/scsi_all.h>
47
48#if NPNP > 0
49#include <i386/isa/pnp.h>
50#endif
51
52static int aha_isa_probe(struct isa_device *dev);
53static int aha_isa_attach(struct isa_device *dev);
54static void aha_isa_intr(void *unit);
55
56struct isa_driver ahadriver =
57{
58 aha_isa_probe,
59 aha_isa_attach,
60 "aha"
61};
62
63/*
64 * Check if the device can be found at the port given
65 * and if so, set it up ready for further work
66 * as an argument, takes the isa_device structure from
67 * autoconf.c
68 */
69static int
70aha_isa_probe(dev)
71 struct isa_device *dev;
72{
73 /*
74 * find unit and check we have that many defined
75 */
76 struct aha_softc *aha;
77 int port_index;
78 int max_port_index;
79
80 aha = NULL;
81
82 /*
83 * Bound our board search if the user has
84 * specified an exact port.
85 */
86 aha_find_probe_range(dev->id_iobase, &port_index, &max_port_index);
87
88 if (port_index < 0)
89 return 0;
90
91 /* Attempt to find an adapter */
92 for (;port_index <= max_port_index; port_index++) {
93 config_data_t config_data;
94 u_int ioport;
95 int error;
96
97 ioport = aha_iop_from_bio(port_index);
98
99 /*
100 * Ensure this port has not already been claimed already
101 * by a PCI, EISA or ISA adapter.
102 */
103 if (aha_check_probed_iop(ioport) != 0)
104 continue;
105 dev->id_iobase = ioport;
106 if (haveseen_isadev(dev, CC_IOADDR | CC_QUIET))
107 continue;
108
109 /* Allocate a softc for use during probing */
110 aha = aha_alloc(dev->id_unit, I386_BUS_SPACE_IO, ioport);
111
112 if (aha == NULL)
113 break;
114
115 /* We're going to attempt to probe it now, so mark it probed */
116 aha_mark_probed_bio(port_index);
117
118 /* See if there is really a card present */
119 if (aha_probe(aha) || aha_fetch_adapter_info(aha)) {
120 aha_free(aha);
121 continue;
122 }
123
124 /*
125 * Determine our IRQ, and DMA settings and
126 * export them to the configuration system.
127 */
128 error = aha_cmd(aha, AOP_INQUIRE_CONFIG, NULL, /*parmlen*/0,
129 (u_int8_t*)&config_data, sizeof(config_data),
130 DEFAULT_CMD_TIMEOUT);
131 if (error != 0) {
132 printf("aha_isa_probe: Could not determine IRQ or DMA "
133 "settings for adapter at 0x%x. Failing probe\n",
134 ioport);
135 aha_free(aha);
136 continue;
137 }
138
139 switch (config_data.dma_chan) {
140 case DMA_CHAN_5:
141 dev->id_drq = 5;
142 break;
143 case DMA_CHAN_6:
144 dev->id_drq = 6;
145 break;
146 case DMA_CHAN_7:
147 dev->id_drq = 7;
148 break;
149 default:
150 printf("aha_isa_probe: Invalid DMA setting "
151 "detected for adapter at 0x%x. "
152 "Failing probe\n", ioport);
153 return (0);
154 }
155 dev->id_irq = (config_data.irq << 9);
156 dev->id_intr = aha_isa_intr;
157 aha_unit++;
158 return (AHA_NREGS);
159 }
160
161 return (0);
162}
163
164/*
165 * Attach all the sub-devices we can find
166 */
167static int
168aha_isa_attach(dev)
169 struct isa_device *dev;
170{
171 struct aha_softc *aha;
172 bus_dma_filter_t *filter;
173 void *filter_arg;
174 bus_addr_t lowaddr;
175
176 aha = aha_softcs[dev->id_unit];
177 if (dev->id_drq != -1)
178 isa_dmacascade(dev->id_drq);
179
180 /* Allocate our parent dmatag */
181 filter = NULL;
182 filter_arg = NULL;
183 lowaddr = BUS_SPACE_MAXADDR_24BIT;
184
185 if (bus_dma_tag_create(/*parent*/NULL, /*alignemnt*/0, /*boundary*/0,
186 lowaddr, /*highaddr*/BUS_SPACE_MAXADDR,
187 filter, filter_arg,
188 /*maxsize*/BUS_SPACE_MAXSIZE_24BIT,
189 /*nsegments*/BUS_SPACE_UNRESTRICTED,
190 /*maxsegsz*/BUS_SPACE_MAXSIZE_24BIT,
191 /*flags*/0, &aha->parent_dmat) != 0) {
192 aha_free(aha);
193 return (-1);
194 }
195
196 if (aha_init(aha)) {
197 printf("aha init failed\n");
198 aha_free(aha);
199 return (-1);
200 }
201
202 return (aha_attach(aha));
203}
204
205/*
206 * Handle an ISA interrupt.
207 * XXX should go away as soon as ISA interrupt handlers
208 * take a (void *) arg.
209 */
210static void
211aha_isa_intr(void *unit)
212{
213 struct aha_softc* arg = aha_softcs[(int)unit];
214 aha_intr((void *)arg);
215}
216
217/*
218 * support PnP cards if we are using 'em
219 */
220
221#if NPNP > 0
222
223static char *ahapnp_probe(u_long csn, u_long vend_id);
224static void ahapnp_attach(u_long csn, u_long vend_id, char *name,
225 struct isa_device *dev);
226static u_long nahapnp = NAHA;
227
228static struct pnp_device ahapnp = {
229 "ahapnp",
230 ahapnp_probe,
231 ahapnp_attach,
232 &nahapnp,
233 &bio_imask
234};
235DATA_SET (pnpdevice_set, ahapnp);
236
237static char *
238ahapnp_probe(u_long csn, u_long vend_id)
239{
240 struct pnp_cinfo d;
241 char *s = NULL;
242
243 if (vend_id != AHA1542_PNP && vend_id != AHA1542_PNPCOMPAT)
244 return (NULL);
245
246 read_pnp_parms(&d, 0);
247 if (d.enable == 0 || d.flags & 1) {
248 printf("CSN %lu is disabled.\n", csn);
249 return (NULL);
250 }
251 s = "Adaptec 1542CP";
252
253 return (s);
254}
255
256static void
257ahapnp_attach(u_long csn, u_long vend_id, char *name, struct isa_device *dev)
258{
259 struct pnp_cinfo d;
32 */
33
34#include "pnp.h"
35
36#include <sys/param.h>
37#include <sys/systm.h>
38#include <sys/kernel.h>
39
40#include <machine/bus_pio.h>
41#include <machine/bus.h>
42
43#include <i386/isa/isa_device.h>
44#include <dev/aha/ahareg.h>
45
46#include <cam/scsi/scsi_all.h>
47
48#if NPNP > 0
49#include <i386/isa/pnp.h>
50#endif
51
52static int aha_isa_probe(struct isa_device *dev);
53static int aha_isa_attach(struct isa_device *dev);
54static void aha_isa_intr(void *unit);
55
56struct isa_driver ahadriver =
57{
58 aha_isa_probe,
59 aha_isa_attach,
60 "aha"
61};
62
63/*
64 * Check if the device can be found at the port given
65 * and if so, set it up ready for further work
66 * as an argument, takes the isa_device structure from
67 * autoconf.c
68 */
69static int
70aha_isa_probe(dev)
71 struct isa_device *dev;
72{
73 /*
74 * find unit and check we have that many defined
75 */
76 struct aha_softc *aha;
77 int port_index;
78 int max_port_index;
79
80 aha = NULL;
81
82 /*
83 * Bound our board search if the user has
84 * specified an exact port.
85 */
86 aha_find_probe_range(dev->id_iobase, &port_index, &max_port_index);
87
88 if (port_index < 0)
89 return 0;
90
91 /* Attempt to find an adapter */
92 for (;port_index <= max_port_index; port_index++) {
93 config_data_t config_data;
94 u_int ioport;
95 int error;
96
97 ioport = aha_iop_from_bio(port_index);
98
99 /*
100 * Ensure this port has not already been claimed already
101 * by a PCI, EISA or ISA adapter.
102 */
103 if (aha_check_probed_iop(ioport) != 0)
104 continue;
105 dev->id_iobase = ioport;
106 if (haveseen_isadev(dev, CC_IOADDR | CC_QUIET))
107 continue;
108
109 /* Allocate a softc for use during probing */
110 aha = aha_alloc(dev->id_unit, I386_BUS_SPACE_IO, ioport);
111
112 if (aha == NULL)
113 break;
114
115 /* We're going to attempt to probe it now, so mark it probed */
116 aha_mark_probed_bio(port_index);
117
118 /* See if there is really a card present */
119 if (aha_probe(aha) || aha_fetch_adapter_info(aha)) {
120 aha_free(aha);
121 continue;
122 }
123
124 /*
125 * Determine our IRQ, and DMA settings and
126 * export them to the configuration system.
127 */
128 error = aha_cmd(aha, AOP_INQUIRE_CONFIG, NULL, /*parmlen*/0,
129 (u_int8_t*)&config_data, sizeof(config_data),
130 DEFAULT_CMD_TIMEOUT);
131 if (error != 0) {
132 printf("aha_isa_probe: Could not determine IRQ or DMA "
133 "settings for adapter at 0x%x. Failing probe\n",
134 ioport);
135 aha_free(aha);
136 continue;
137 }
138
139 switch (config_data.dma_chan) {
140 case DMA_CHAN_5:
141 dev->id_drq = 5;
142 break;
143 case DMA_CHAN_6:
144 dev->id_drq = 6;
145 break;
146 case DMA_CHAN_7:
147 dev->id_drq = 7;
148 break;
149 default:
150 printf("aha_isa_probe: Invalid DMA setting "
151 "detected for adapter at 0x%x. "
152 "Failing probe\n", ioport);
153 return (0);
154 }
155 dev->id_irq = (config_data.irq << 9);
156 dev->id_intr = aha_isa_intr;
157 aha_unit++;
158 return (AHA_NREGS);
159 }
160
161 return (0);
162}
163
164/*
165 * Attach all the sub-devices we can find
166 */
167static int
168aha_isa_attach(dev)
169 struct isa_device *dev;
170{
171 struct aha_softc *aha;
172 bus_dma_filter_t *filter;
173 void *filter_arg;
174 bus_addr_t lowaddr;
175
176 aha = aha_softcs[dev->id_unit];
177 if (dev->id_drq != -1)
178 isa_dmacascade(dev->id_drq);
179
180 /* Allocate our parent dmatag */
181 filter = NULL;
182 filter_arg = NULL;
183 lowaddr = BUS_SPACE_MAXADDR_24BIT;
184
185 if (bus_dma_tag_create(/*parent*/NULL, /*alignemnt*/0, /*boundary*/0,
186 lowaddr, /*highaddr*/BUS_SPACE_MAXADDR,
187 filter, filter_arg,
188 /*maxsize*/BUS_SPACE_MAXSIZE_24BIT,
189 /*nsegments*/BUS_SPACE_UNRESTRICTED,
190 /*maxsegsz*/BUS_SPACE_MAXSIZE_24BIT,
191 /*flags*/0, &aha->parent_dmat) != 0) {
192 aha_free(aha);
193 return (-1);
194 }
195
196 if (aha_init(aha)) {
197 printf("aha init failed\n");
198 aha_free(aha);
199 return (-1);
200 }
201
202 return (aha_attach(aha));
203}
204
205/*
206 * Handle an ISA interrupt.
207 * XXX should go away as soon as ISA interrupt handlers
208 * take a (void *) arg.
209 */
210static void
211aha_isa_intr(void *unit)
212{
213 struct aha_softc* arg = aha_softcs[(int)unit];
214 aha_intr((void *)arg);
215}
216
217/*
218 * support PnP cards if we are using 'em
219 */
220
221#if NPNP > 0
222
223static char *ahapnp_probe(u_long csn, u_long vend_id);
224static void ahapnp_attach(u_long csn, u_long vend_id, char *name,
225 struct isa_device *dev);
226static u_long nahapnp = NAHA;
227
228static struct pnp_device ahapnp = {
229 "ahapnp",
230 ahapnp_probe,
231 ahapnp_attach,
232 &nahapnp,
233 &bio_imask
234};
235DATA_SET (pnpdevice_set, ahapnp);
236
237static char *
238ahapnp_probe(u_long csn, u_long vend_id)
239{
240 struct pnp_cinfo d;
241 char *s = NULL;
242
243 if (vend_id != AHA1542_PNP && vend_id != AHA1542_PNPCOMPAT)
244 return (NULL);
245
246 read_pnp_parms(&d, 0);
247 if (d.enable == 0 || d.flags & 1) {
248 printf("CSN %lu is disabled.\n", csn);
249 return (NULL);
250 }
251 s = "Adaptec 1542CP";
252
253 return (s);
254}
255
256static void
257ahapnp_attach(u_long csn, u_long vend_id, char *name, struct isa_device *dev)
258{
259 struct pnp_cinfo d;
260 struct isa_device *dvp;
261
262 if (dev->id_unit >= NAHATOT)
263 return;
264
265 if (read_pnp_parms(&d, 0) == 0) {
266 printf("failed to read pnp parms\n");
267 return;
268 }
269
270 write_pnp_parms(&d, 0);
271
272 enable_pnp_card();
273
274 dev->id_iobase = d.port[0];
275 dev->id_irq = (1 << d.irq[0]);
276 dev->id_intr = aha_intr;
277 dev->id_drq = d.drq[0];
278
279 if (dev->id_driver == NULL) {
280 dev->id_driver = &ahadriver;
260
261 if (dev->id_unit >= NAHATOT)
262 return;
263
264 if (read_pnp_parms(&d, 0) == 0) {
265 printf("failed to read pnp parms\n");
266 return;
267 }
268
269 write_pnp_parms(&d, 0);
270
271 enable_pnp_card();
272
273 dev->id_iobase = d.port[0];
274 dev->id_irq = (1 << d.irq[0]);
275 dev->id_intr = aha_intr;
276 dev->id_drq = d.drq[0];
277
278 if (dev->id_driver == NULL) {
279 dev->id_driver = &ahadriver;
281 dvp = find_isadev(isa_devtab_tty, &ahadriver, 0);
282 if (dvp != NULL)
283 dev->id_id = dvp->id_id;
280 dev->id_id = isa_compat_nextid();
284 }
285
286 if ((dev->id_alive = aha_isa_probe(dev)) != 0)
287 aha_isa_attach(dev);
288 else
289 printf("aha%d: probe failed\n", dev->id_unit);
290}
291#endif
281 }
282
283 if ((dev->id_alive = aha_isa_probe(dev)) != 0)
284 aha_isa_attach(dev);
285 else
286 printf("aha%d: probe failed\n", dev->id_unit);
287}
288#endif